Ensure that HttpConfiguration.EnsureInitialized()
If you do it at the end of Application_Start it will be too late, as WebApiConfig.Register has been called.
The best way to resolve this is to use new initialization method by replacing in Global.asax :
WebApiConfig.Register(GlobalConfiguration.Configuration);
by
GlobalConfiguration.Configure(WebApiConfig.Register);
See @gentiane's answer below for the correct way to handle this now.
At the end of the Application_Start
method in Global.Asax.cs
try adding:-
GlobalConfiguration.Configuration.EnsureInitialized();
I actually got this error when I was using Attribute Routing within my WebApi.
I had
[Route("webapi/siteTypes/{siteTypeId"]
instead of
[Route("webapi/siteTypes/{siteTypeId}"]
for my route and got this error. I had simply missed out the closing curly bracket. Once I added it back in, this error didn't occur again.
This is old, but is the first result on google when searching for this error. After quite a bit of digging I was able to figure out what was going on.
tldr:
All GlobalConfiguration.Configure does is invoke your action and call EnsureInitialized(). config.MapAttributeRoutes() must be called before EnsureInitialized() since EnsureInitialized only runs once.
Meaning: if you're coming from an existing Mvc project, all you have to do is:
- Add GlobalConfiguration.Configuration.EnsureInitialized(); to the bottom of your Application_Start method.
OR
- Move your entire configuration into a single call to GlobalConfiguration.Configure:
GlobalConfiguration.Configure(config =>
{
WebApiConfig.Register(config);
config.MapAttributeRoutes();
...
});
Digging Deeper
HttpConfiguration.Configuration has an "Initializer" property defined like this:
public Action<HttpConfiguration> Initializer;
HttpConfiguration.EnsureInitialized() runs this action and sets _initialized to true
public void EnsureInitialized()
{
if (_initialized)
{
return;
}
_initialized = true;
Initializer(this);
}
HttpConfiguration.MapAttributeRoutes calls internal method AttributeRoutingMapper.MapAttributeRoutes which sets HttpConfiguration.Initializer
public static void MapAttributeRoutes(...)
{
RouteCollectionRoute aggregateRoute = new RouteCollectionRoute();
configuration.Routes.Add(AttributeRouteName, aggregateRoute);
...
Action<HttpConfiguration> previousInitializer = configuration.Initializer;
configuration.Initializer = config =>
{
previousInitializer(config);
...
};
}
GlobalConfiguration.Configure runs EnsureInitialized immediately after invoking your action:
public static void Configure(Action<HttpConfiguration> configurationCallback)
{
if (configurationCallback == null)
{
throw new ArgumentNullException("configurationCallback");
}
configurationCallback.Invoke(Configuration);
Configuration.EnsureInitialized();
}
Don't forget, if you run in to a wall, the source for asp.net is available at http://aspnetwebstack.codeplex.com/SourceControl/latest
I've had a related issue. Sometimes calling GlobalConfiguration.Configure
multiple times triggers this error. As a workaround, I've put all configuration initialization logic in one place.