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

时间:2012-03-14 13:10:48

标签: asp.net rest asp.net-mvc-4 asp.net-web-api

我正在使用RESTful API设计,以及我发布到Programmers StackExchange网站here的内容协商问题之一。

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

  1. 如果在网址上指定了扩展名(例如GET /api/search.json/api/search.xml),则覆盖MVC4中的默认内容协商行为
  2. 如果未指定扩展名,请使用检查application/xmlapplication.json的接受标头值的默认行为。
  3. 捕获此扩展并修改内容协商行为的最简洁/最直接的方法是什么?

1 个答案:

答案 0 :(得分: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();
    }