2014-07-03 83 views
1

我在ASP.Net中有一個WebAPI 2.0項目,我在其中實現了一個自定義的DefaultContractResolver,以便我可以控制如何使用JSON.Net將我的實體序列化爲JSON;不過,我不確定如何告訴框架使用我的自定義實現。我還想知道是否有可能爲特定控制器/操作更改ContractResolver。我應該在哪裏插入我的自定義DefaultContractResolver JSON.NET?

謝謝!

---編輯03/07/2014 我已經想通過創建一個新的ConfigSettings對象並手動解析對象來了解如何使用我的自定義實現;然而,生成的JSON會被序列化兩次(它有額外的\ r \ n字符)。這是因爲webAPI控制器默認序列化響應,所以我想改變以覆蓋該行爲......這是正確的方式嗎?

+0

由斯科特艾倫幫忙嗎[這篇短文](http://odetocode.com/blogs/scott/archive/2013/03/25/asp-net-webapi-tip-3-camelcasing-json.aspx)? – Jonesopolis

+0

偉大的文章,雖然我想避免更改JsonConverter的全局設置。這[鏈接](http://decompile.it/blog/2011/08/08/overriding-the-default-serialization-behavior-in-json-net/)[鏈接]看起來不錯,我正在測試它出。 –

回答

2

我剛剛度過了自己的痛苦,我需要一個每個請求的作品。您可以使用該方法並返回相同的媒體格式器。我發現將GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver設置爲格式化程序對於每個請求的需求有點不可靠,即使我嘗試在該類的單個實例中處理每個請求的需求。不過你可以嘗試設置你的ContractResolver實例有,在App_Start代碼

我結束了創建自定義JsonMediaTypeFormatter,檢查是否存在對請求的配置ContractResolver,你可以只返回一個相同的旋轉變壓器的地方:

public class DynamicJsonMediaTypeFormatter : JsonMediaTypeFormatter 
{ 
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, System.Net.Http.HttpRequestMessage request, System.Net.Http.Headers.MediaTypeHeaderValue mediaType) 
{ 
// shown is getting the current formatter, but you can return an instance you prefer 
    var formatter = base.GetPerRequestFormatterInstance(type, request, mediaType) as JsonMediaTypeFormatter; 

// Here I had more code to get the resolver based on request, skipped 
    ((JsonMediaTypeFormatter)formatter).SerializerSettings.ContractResolver = <YourContractResolverInstance>; 
    return formatter; 
} 
} 

我認爲你已經想出了那部分,但你的合約解析器可以重寫`CreateProperties'並且有你自己的邏輯決定什麼json屬性將會出現以及它們將使用什麼名字(爲了完整性和其他好處而添加讀者):

public class DynamicContractResolver : DefaultContractResolver 
{ 
... 
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization){ 
    ... 
} 
+0

這正是我決定創建自己的實現的原因,以覆蓋CreateProperties方法。 –

1

我最終改變我的方法的返回類型是這樣的:

Asume我們有這個簡單的Foo類:

public class Foo 
{ 
    public string Bar {get; set;} 
} 

與ASP的WebAPI 2.0 GET腳手架控制器方法是這樣的:

// GET api/Foo 
public IQueryable<Foo> GetFoos() 
{ 
    var foos = GetAListOfFoosFromSomewhere() //returns an IQueryable<Foo> 
    return Foos 
} 

請注意,框架會自動將Foos序列化爲JSON。

所以我所做的是改變方法如下:

// GET api/Foo 
public HttpResponseMessage GetFoos() 
{ 
    var foos = GetAListOfFoosFromSomewhere(); //returns an IQueryable<Foo> 
    var settings = new JsonSerializerSettings() 
    { 
    ContractResolver= new MyCustomContractResolver(), //Put your custom implementation here 
    //Also set up ReferenceLoopHandling as appropiate 
    }; 
    var jsoncontent = JsonConvert.SerializeObject(foos, settings); 
    var response = new HttpResponseMessage(HttpStatusCode.OK) 
    { 
     Content = new StringContent(jsoncontent, Encoding.UTF8, "application/json") 
    }; 
    return response; 
} 

在我的解決方案我增加了一個方便易用的方法來創建HttpResponseMessage所以看起來有點像這樣:

public HttpResponseMessage GetFoos() 
{ 
    var foos = GetAListOfFoosFromSomewhere() //returns an IQueryable<Foo> 
    return CreateResponse(foos); 
} 

這發帖者mercury2269真的很有幫助。

+0

這種方法的一個問題是,如果您對自定義合約解析程序有很多用途,那麼最終會在整個項目中產生大量複製代碼 –

+0

並非如此,這就是我添加便捷方法的原因。 –

相關問題