2015-10-20 91 views
0

我想執行自定義序列化,所有的快樂路徑代碼工作,但空值路徑不表現我想。NullValueHandling.Ignore與JsonConverter :: WriteJson

我已經將串行器設置設置爲NullValueHandling.Ignore和我的對象圖的其他部分爲空(並且不使用我的自定義序列化)刪除了空值。它看起來像Newtonsoft序列化程序寫入字符串生成器,所以我們應該能夠'倒回'任何書面json令牌,但我不知道如何不寫任何東西。

無所事事,只是返回導致序列化程序引發異常,因爲JSON將無效。

任何線索?

public class SpecialConvertor : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     if (value == null || (int)value == 0) 
     { 
      if (serializer.NullValueHandling == NullValueHandling.Ignore) 
      { 
       //how to make this work? 
      } 
      else 
      { 
       writer.WriteNull(); 
      } 
      return; 
     } 
     // the rest of WriteJson 
    } 
    // the rest of SpecialConvertor 
} 
+1

我無法重現此問題。 1)'NullValueHandling'用於對象引用。由於你的屬性是一個整數,你可能需要['DefaultValueHandling = DefaultValueHandling.Ignore'](http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_DefaultValueHandling.htm)。 2)如果值爲null,則不調用'JsonConverter.WriteJson()',而Json.NET本身寫入空名稱和值。也許你有一些更高級別的轉換器無法檢查'serializer.NullValueHandling'?有關可能出錯的示例,請參閱https://dotnetfiddle.net/dWfJ0o。 – dbc

+0

此外,它可以直接序列化到一個流,例如['GZipStream'](https://stackoverflow.com/questions/32943899/can-i-decompress-and-deserialize-a-file-using-streams ),爲此無法倒帶 – dbc

+1

@dbc很好的工作,不知道我是如何錯過的。漫長的一天等等。從可能爲空的枚舉或者缺乏對序列化程序的信任時,可能會進行空值檢查。該調用將值用作默認(零)值,而不是空值。我看到的是我的,我(錯誤地)寫出來的。稍後我會更詳細地閱讀dotnetfiddle。謝謝。 (如果您需要信用,請添加爲答案) –

回答

2

NullValueHandling用於對象引用。在你的例子中,你的值是一個整數。要使用默認值省略整數屬性,請使用設置DefaultValueHandling = DefaultValueHandling.Ignore

null檢查WriteJson()應該是不必要的,因爲Json.NET從不會調用具有空值的轉換器。相反,它會自己寫入名稱&空值 - 如果是NullValueHandling == NullValueHandling.Ignore,則不寫。所以檢查空和倒帶不應該是必需的。

的對象屬性的空值時,空值處理或缺省值處理是Ignore如果你的轉換器之一WriteJson明確寫道:它可能仍然被寫入。爲了防止這種情況,您可以檢查設置並跳過像這樣的空值:

public class MyClassConverter : JsonConverter 
{ 
    const string Prefix = "My Value Is: "; 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var myClass = (MyClass)value; 
     writer.WriteStartObject(); 
     if (myClass.StringValue != null 
      || (serializer.NullValueHandling != NullValueHandling.Ignore 
       && (serializer.DefaultValueHandling & DefaultValueHandling.Ignore) != DefaultValueHandling.Ignore)) 
     { 
      writer.WritePropertyName("StringValue"); 
      if (myClass.StringValue == null) 
       writer.WriteNull(); 
      else 
       serializer.Serialize(writer, Prefix + myClass.StringValue); 
     } 
     writer.WriteEndObject(); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.Null) 
      return null; 
     var s = (string)JValue.Load(reader); 
     if (s.StartsWith(Prefix)) 
      s = s.Substring(Prefix.Length); 
     return s; 
    } 

    public override bool CanConvert(Type objectType) { return objectType == typeof(MyClass); } 
} 

[JsonConverter(typeof(MyClassConverter))] 
public class MyClass 
{ 
    public string StringValue { get; set; } 
} 
相關問題