I'm working through a RESTful API design, and one of the questions I have about content negotiation I've posted to the Programmers StackExchange site here.
Based on that, I'm interested in how I would support the following behavior in MVC4:
GET /api/search.json
or /api/search.xml
), override the default content negotiation behavior in MVC4application/xml
or application.json
.What would be the cleanest / most straightforward way of capturing this extension and modifying the content negotiation behavior?
You can use the UriPathExtensionMapping in the formatters to accomplish that. Those mappings let you "assign" an extension to a formatter, so that they're given precedence during content negotiation. You also need to add a route so that requests with "extension" are also accepted. The code below shows the changes required in the default template to enable this scenario.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "Api with extension",
routeTemplate: "api/{controller}.{ext}/{id}",
defaults: new { id = RouteParameter.Optional, ext = RouteParameter.Optional }
);
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
GlobalConfiguration.Configuration.Formatters.XmlFormatter.AddUriPathExtensionMapping("xml", "text/xml");
GlobalConfiguration.Configuration.Formatters.JsonFormatter.AddUriPathExtensionMapping("json", "application/json");
BundleTable.Bundles.RegisterTemplateBundles();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With