2015-11-02 77 views
3

的Web API使用Json.Net格式化程序序列化JSON的響應,它允許您在啓動時使用很方便地自定義生成的JSON格式爲整個應用程序:設置JSON駝峯

config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

這使您可以解決C#語法偏好PascalCase和喜歡使用camelCase的基於JavaScript的客戶端之間的問題。但是,如果在API上全局設置此值,而不考慮客戶端請求實際來自誰,似乎認爲API將只有一種類型的客戶端,並且您爲API設置的任何內容都是其必須的方式。

有多個客戶端類型爲我的API(JavaScript的,的iOS,安卓,C#),我正在尋找一種方法來設置Json.Net SerializerSettings 每個請求,使得客戶端可以通過一些要求他們的首選格式意味着(可能是一個自定義頭或queryString參數)來覆蓋默認值。

在Web API中設置每個請求Json.Net SerializerSettings的最佳方式是什麼?

回答

9

在Rick Strahl的blog post關於創建JSONP媒體類型格式化程序的幫助下,我提出了一個解決方案,允許API根據客戶機請求動態地從camelCase切換到PascalCase。

創建一個MediaTypeFormatter,它從默認的JsonMediaTypeFormatter派生並重寫GetPerRequestFormatterInstance方法。在這裏你可以實現你的邏輯來根據請求設置串行器設置。

public class JsonPropertyCaseFormatter : JsonMediaTypeFormatter 
{ 
    private readonly JsonSerializerSettings globalSerializerSettings; 

    public JsonPropertyCaseFormatter(JsonSerializerSettings globalSerializerSettings) 
    { 
     this.globalSerializerSettings = globalSerializerSettings; 
     SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json")); 
     SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript")); 
    } 

    public override MediaTypeFormatter GetPerRequestFormatterInstance(
     Type type, 
     HttpRequestMessage request, 
     MediaTypeHeaderValue mediaType) 
    { 
     var formatter = new JsonMediaTypeFormatter 
     { 
      SerializerSettings = globalSerializerSettings 
     }; 

     IEnumerable<string> values; 

     var result = request.Headers.TryGetValues("X-JsonResponseCase", out values) 
      ? values.First() 
      : "Pascal"; 

     formatter.SerializerSettings.ContractResolver = 
      result.Equals("Camel", StringComparison.InvariantCultureIgnoreCase) 
       ? new CamelCasePropertyNamesContractResolver() 
       : new DefaultContractResolver(); 

     return formatter; 
    } 
} 

注意,我採取JsonSerializerSettings參數的構造函數PARAM這樣我們就可以繼續使用WebApiConfig設置任何其他JSON的設置,我們要使用,讓他們在這裏仍然適用。

爲了然後註冊此格式,在您的WebApiConfig:具有的X-JsonResponseCase: Camel頭值將在響應收到駝峯屬性名稱

config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new StringEnumConverter()); 
config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; 
config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local; 

config.Formatters.Insert(0, 
    new JsonPropertyCaseFormatter(config.Formatters.JsonFormatter.SerializerSettings)); 

現在請求。顯然你可以改變這個邏輯來使用你喜歡的任何頭文件或查詢字符串參數。