如何在MVC4中扩展内容协商行为?

Bra*_*ton 4 asp.net rest asp.net-mvc-4 asp.net-web-api

我正在通过RESTful API设计,以及我在此处发布到Programmers StackExchange站点的内容协商问题之一.

基于此,我对如何在MVC4中支持以下行为感兴趣:

  1. 如果在URL上指定了扩展名(例如,GET /api/search.json/api/search.xml),则覆盖MVC4中的默认内容协商行为
  2. 如果未指定扩展名,请使用检查application/xml或的接受标头值的默认行为application.json.

捕获此扩展和修改内容协商行为的最干净/最直接的方法是什么?

car*_*ira 9

您可以在格式化程序中使用UriPathExtensionMapping来完成此操作.这些映射允许您为格式化程序"分配"扩展,以便在内容协商期间优先使用它们.您还需要添加路由,以便也可以接受带有"扩展名"的请求.下面的代码显示了启用此方案的默认模板中所需的更改.

    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();
    }
Run Code Online (Sandbox Code Playgroud)