2012-03-14 49 views
4

我通過一個RESTful API的設計工作,而我有我已經發布了程序員StackExchange網站here內容協商的問題之一。如何擴展MVC4中的內容協商行爲?

基於這一點,我很感興趣,我將如何支持MVC4以下行爲:

  1. 如果URL中指定分機號(例如,GET /api/search.json/api/search.xml),覆蓋默認的內容協商在MVC4
  2. 如果沒有指定分機,使用行爲進行檢查或application/xmlapplication.json接受頭值的默認行爲。

捕獲此擴展並修改內容協商行爲的最簡潔/最直接的方式是什麼?

回答

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(); 
    } 
+0

真棒!這些格式擴展也允許你通過查詢字符串參數驅動它,我認爲我更喜歡它。 – 2012-03-14 18:50:36

+0

@BrandonLinton - querystring參數如何爲您工作?你有什麼額外的東西來攔截和轉換嗎? – drzaus 2012-05-07 15:14:41

+0

@drzaus相反AddUriPathExtensionMapping'的',使用'AddQueryStringMapping'擴展操作,就像這樣:'formatter.AddQueryStringMapping( 「返回類型」, 「JSON」, 「應用/ JSON」);' – 2012-05-07 18:36:38