Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web API Attribute Routes in MVC 5 exception: The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized()

On an MVC 5 with Web API I have the following, using only Attribute Routes:

RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteTable.Routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.([iI][cC][oO]|[gG][iI][fF])(/.*)?" }); // TODO: Check for Apple Icons

RouteTable.Routes.MapMvcAttributeRoutes();
GlobalConfiguration.Configuration.MapHttpAttributeRoutes();
AreaRegistration.RegisterAllAreas();

In the RouteTable all the MVC routes were created ... But not the API ones ...

I checked the RouteTable.Routes and I see an exception:

The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.

at System.Web.Http.Routing.RouteCollectionRoute.get_SubRoutes() at System.Web.Http.Routing.RouteCollectionRoute.GetEnumerator() at System.Linq.SystemCore_EnumerableDebugView`1.get_Items()

For testing this I added only two Web Api actions to the project:

[RoutePrefix("api")]
public class StatApiController : ApiController {

  [Route("stats/notescreateddaily"), HttpGet]
  public IHttpActionResult NotesCreatedDaily() {
    // Some code
  }

  [Route("stats/userscreateddaily"), HttpGet]
  public IHttpActionResult UsersCreatedDaily() {
    // Some code
  }

}

Am I missing something?

Thank You, Miguel

like image 807
Miguel Moura Avatar asked Nov 09 '13 19:11

Miguel Moura


People also ask

What is [route] attribute in MVC?

If we are defining Routes by using the [Route] attribute is called Attribute Routing. It provides you more control over the URIs by defining routes directly on actions and controllers in your ASP.NET MVC application. Note: The earlier style of routing, called convention-based routing, is still fully supported by ASP.NET MVC 5.

How to enable attribute routing in web API 1?

In Web API 1, by default, Attribute Routing is not available, but in Web API 2 Attribute Routing can be used easily without adding external library. Thus, let's go to know how to enable this feature in Web API 1.

How to use API in MVC with school route template?

For example, request url is http://localhost:1234/api/myschool is matched with School route template, so it will be handled by SchoolController. Note: The reason to use api in the route template is just to avoid confusion between MVC controller and Web API controller. You can use any pattern based on your app architecture.

Can I use MVC and convention-based routing in one project?

Yes, both the routing mechanisms can be combined in a single ASP.NET MVC project. The controller action methods that have the [Route] attribute uses Attribute Routing, and the action methods without the [Route] attribute uses Convention-based routing.


3 Answers

The solution is in fact replacing:

GlobalConfiguration.Configuration.MapHttpAttributeRoutes();

By:

GlobalConfiguration.Configure(x => x.MapHttpAttributeRoutes());

That was a change in Web API 2.

like image 160
Miguel Moura Avatar answered Oct 19 '22 17:10

Miguel Moura


The solution is to call GlobalConfiguration.Configuration.EnsureInitialized(); after all your Web API related configuration is done, but I am curious as to why your registrations look like this...What kind of project template did you use to create the MVC5 project?...The predefined templates that come with Visual Studio has a structure which helps minimize route ordering problems and so would recommend using them, so wondering why your configuration structure looks like that...

like image 42
Kiran Avatar answered Oct 19 '22 17:10

Kiran


I am having the same problem after I upgrade all my web services project using ASP.Net Web API 4.0 to 4.5 and using Web API 2.2 with Cors library. I managed to successfully solve the problem. What I did was eliminating or commenting out the following statement at the RouteConfig.cs file at App_Start folder:`

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace myNameSpace.Configurations
{
    public static class RouteConfig
    {

        public static void Register(HttpConfiguration config)
        {
            // Web API routes
            //DON'T USE THIS. IT WILL GIVE PROBLEMS IN INSTANTIATION OF OBJECTS
            //config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "LocationData",
                routeTemplate: "dataservices/locations/{controller}/{action}/{id}",
                defaults: new {action = "Index", id = RouteParameter.Optional }
            );


            config.Routes.MapHttpRoute(
                name: "ProfileData",
                routeTemplate: "dataservices/profiles/{controller}/{action}/{id}",
                defaults: new { action = "Index", id = RouteParameter.Optional }
            );



            config.Routes.MapHttpRoute(
                name: "DefaultRoute",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }

    }
}

On my Global.asax.cs file I am using the old routing registration

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Net.Http.Formatting;

using myNameSpace.IoC;
using myNameSpace.Configurations; // Here actually I change the protected void Application_Start() to protected void Configuration() and change the folder to configuration instead on App_Start
using myNameSpace.Controllers.ExceptionSchema;
using myNameSpace.Filters.HttpFilters;

namespace myNameSpace
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        public static void RegisterApis(HttpConfiguration config)
        {
            config.Filters.Add(new CustomHttpExceptionFilter());
        }
        protected void Application_Start()
        {
            //AreaRegistration.RegisterAllAreas();
            RegisterApis(GlobalConfiguration.Configuration);


            var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
            json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
            GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);


            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.Register(GlobalConfiguration.Configuration);
        }
    }
}

Here is the reason: Attribute Routing in Web API 2

Note: Migrating From Web API 1

Prior to Web API 2, the Web API project templates generated code like this:

protected void Application_Start()
{
    // WARNING - Not compatible with attribute routing.
    WebApiConfig.Register(GlobalConfiguration.Configuration);
}

If attribute routing is enabled, this code will throw an exception. If you upgrade an existing Web API project to use attribute routing, make sure to update this configuration code to the following:

protected void Application_Start()
{
    // Pass a delegate to the Configure method.
    GlobalConfiguration.Configure(WebApiConfig.Register);
}

I am using the old route and I decided not to use attribute routing. So take OUT THAT statement

like image 23
Snow Attitudes Avatar answered Oct 19 '22 17:10

Snow Attitudes