2016-08-15 19 views
2

我有很多數據契約的系統中的成員都裝飾有:JSON.net不包括錯誤的零特性與EmitDefaultValue

[DataMember(EmitDefaultValue = false)] 

我有,我需要包括各成員的情況下,當空時序列化爲JSON。無論我選擇什麼串行器設置,我都無法使其工作。

[TestMethod] 
    public void SerializationTest() 
    { 

     var contract = Activator.CreateInstance(typeof(TestContract)); 

     var formatter = new JsonMediaTypeFormatter 
     { 
      SerializerSettings = new JsonSerializerSettings 
      { 
       NullValueHandling = NullValueHandling.Include, 
       DefaultValueHandling = DefaultValueHandling.Ignore, 
       TypeNameHandling = TypeNameHandling.All, 
       ContractResolver = new DataContractResolver(), 
       Binder = new DataContractBinder() 
      } 
     }; 

     var result = JsonConvert.SerializeObject(contract, formatter.SerializerSettings); 
    } 

我甚至創建一個自定義數據合同解析器可提供每屬性的附加覆蓋。

 protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
    {       
     var property = base.CreateProperty(member, MemberSerialization.Fields);       
     property.NullValueHandling = NullValueHandling.Include;    
     property.DefaultValueHandling = DefaultValueHandling.Ignore; 
     property.ShouldSerialize = o => true; 
     return property; 
    } 

我試過的空值處理和缺省值處理忽略所述發送默認值= FALSE的所有變化。根據json淨文檔,這些設置應該給我對我的空屬性。在我去調試json網絡源代碼之前,有什麼我失蹤了嗎?

回答

2

您需要設置property.DefaultValueHandling = DefaultValueHandling.Include,而不是DefaultValueHandling.Ignore合同解析:

public class DataContractResolver : DefaultContractResolver 
{ 
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
    { 
     var property = base.CreateProperty(member, memberSerialization); 
     property.NullValueHandling = NullValueHandling.Include; 
     property.DefaultValueHandling = DefaultValueHandling.Include; 
     property.ShouldSerialize = o => true; 
     return property; 
    } 
} 

Json.NET同時檢查DefaultValueHandlingNullValueHandling序列化的成員之前,和檢查都以通爲會員被序列化。而且,正如您已經注意到的,如果明確地設置合同的屬性,那麼這將覆蓋JsonSerializerSettings中的設置。這解釋了爲什麼需要自定義合約解析器。

您可能想要cache the contract resolver以獲得最佳性能。

+0

有趣。在配置SerializerSettings時,我嘗試了這些設置組合。我在覆蓋中沒有這麼做,因爲文檔使得它聽起來就像你應該忽略的一樣。如果使用這些設置並使用自定義解析器,它確實有效。似乎更好的方法是告訴設置是否允許覆蓋屬性。謝謝。 – twifosp