2

Is it possible to host MVC and Web API controllers using the same routes but serving different content?

What I would like is for the correct controller to be selected based on the content type in the Accept header of the request.

For example:

GET /users/1 [Accept: text/html] would invoke an MVC Response.
GET /users/1 [Accept: application/json] would invoke a Web API response.

I realise that it is possible to render Razor views and return HTML directly from Web API, but then I wouldn't be able to use the MVC goodness for rendering my main site (unless someone tells me that you can do everything in Web API that MVC can do!)

related (but not the same) question: ASP.NET MVC 4 ApiController and Normal Controller Routes

Community
  • 1
  • 1
phil_rawlings
  • 983
  • 10
  • 14

1 Answers1

3

As you have your question posted and out of the box, no.

You could do some goodness in an HttpHandler or HttpModule to detect the requested datatype and redirect your request to your WebAPI project.

Or, you could define your routes and have your WebAPI project accept requests that have a .json or even .xml extention and make your API requests appropriately based on your routes

routes.MapRoute("Default", "{controller}/{action}/{id}.json", new { controller = "Home", action = "Index" });

EDIT 1: If you need to handle multiple content types you could define your routes like below and handle the content type in your controller action

routes.MapRoute("Default", "{controller}/{action}/{id}.{contentType}", new { controller = "Home", action = "Index" });
Anthony Shaw
  • 8,146
  • 4
  • 44
  • 62
  • 1
    I like the idea of an HttpHandler or HttpModule, I was considering adding logic to the MVC controller to redirect to api/users/1 if the request is for anything other than HTML but moving it further up the pipeline sounds like a better idea. I'm not so keen on the extension idea since we have multiple content types (json, xml and messagepack) and attribute routing rather than global routes. – phil_rawlings Jan 15 '14 at 15:41
  • 1
    added an edit with an alternative to handle contentType, you could use a regex filter in addition to filter only the allowed extension types as well. – Anthony Shaw Jan 15 '14 at 15:45