Question

This is a random one, and it has me flummoxed.

I just updated my project to WebAPI 2 so I can make use of the new Attribute Routing feature. I followed the tutorial on the official site, and ended up with config in my global file like this:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RouteConfig.RegisterRoutes(RouteTable.Routes);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    GlobalConfiguration.Configure(WebApiConfig.Register);
}

Then in the WebApiConfig class I'm setting up attribute routing like so:

public static void Register(HttpConfiguration config)
{
    config.DependencyResolver = new DependencyResolverFactory();
    config.MapHttpAttributeRoutes();
}

Then I want an action method with route "api/users/{id}":

[Route("api/users/{id}")]
public UserAccountModel GetUserAccount(string id)
{
    return _userAccountService.GetAccountDetails(id);
}

This all looks good to me so far. However, when I try and hit this route I get an exception:

The IControllerFactory 'withoomph.Common.Ioc.DependencyControllerFactory' did not return a controller for the name 'api'.

The DependencyControllerFactory is where I doing my dependency injection for my MVC controllers, so not sure why it is going there.

The strange thing is, if I change the route so it has an extra part to it:

[Route("api/users/test/{id}")]
public UserAccountModel GetUserAccount(string id)
{
    return _userAccountService.GetAccountDetails(id);
}

It works! I have tried this out in a few different controllers, with different names, using api, not using api etc. And it is always the same: if the route has less than 4 parts to it, it doesn't work. Any more than 4, it works.

Does anyone know what he fudge is going on??!!

Was it helpful?

Solution

You need to re-order your registration code above as your request url is being matched by MVC routes as its more generic (ex: {controller}/{action}/{id}) compared to Web API's specific route (api/{controller}/{id}). As per routing guidelines, more specific routes must be registered before generic routes.

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);

        RouteConfig.RegisterRoutes(RouteTable.Routes);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top