5

I have a project that is used solely for API requests into our app and we are using an ASP.NET MVC 4 project. We have some Controllers that derive from the ApiController and others that derive from the normal Controller class. The issue is that I don't want to have the default routing for the ApiControllers of api/XXXXX/. I want the same routing to be used for the ApiControllers as the non-Api Controllers, namely {controller}/{action}/{id}. I tried adding the following routes

routes.MapHttpRoute(
    name: "Api",
    routeTemplate: "{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

This will make it so that my ApiControllers are accessible using the normal {controller}/{action} routing but "normal" Controllers are no longer accessible. If I get rid of the MapHttpRoute the opposite happens.

Is there any way to have ApiControllers and "normal" Controllers accessible via the same url routes?

Ed Chapel
  • 6,842
  • 3
  • 30
  • 44
Nick Olsen
  • 6,299
  • 11
  • 53
  • 75
  • 1
    It seems to me what you're asking is "If I give MVC two identical routes to choose from, can **it** decide whether **I** want standard or API?". If that's correct, then the answer is a simple no. **It** can only do as it's told, it can't make decisions. – Paul Fleming Aug 24 '13 at 21:22
  • 1
    I guess I didn't realize it had to make any decision at the time of routing. I thought it would figure out the api logic at the controller level not the routing level. Didn't realize it needed to know right up front. I did find out I can just explicitly define each controller name as a new route and it will work though. Requires a route definition for each controller but it's better than nothing. – Nick Olsen Aug 24 '13 at 23:57
  • @flem - there is some additional information that can be used to determine which controller to use: The content type in the `Accept` header on the request. If there was a way to tell MVC to respond to HTML requests and forward other requests onto the Web API controller then that would work. I'm not saying its possible or practical, it would just be nice if MVC and WebAPI could play nice together :-) For example: GET /users/1 [Accept: text/html] invokes an MVC Response. GET /users/1 [Accept: application/json] invokes a Web API response. – phil_rawlings Jan 15 '14 at 15:13

1 Answers1

6

The only way this can be done from what I can see is to explicitly name each API controller. Below I have a SomeApiController class.

routes.MapHttpRoute(
    name: "SomeApiController",
    routeTemplate: "SomeApi/{action}/{id}",
    defaults: new { controller = "SomeApi", id = RouteParameter.Optional }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Nick Olsen
  • 6,299
  • 11
  • 53
  • 75