NullValueHandling.Ignore与JsonConverter :: WriteJson

我正在尝试执行自定义序列化,所有快乐路径代码都可以工作,但是空值路径不符合我的要求。

我已将序列化程序设置设置为NullValueHandling.Ignore并且我的对象图的其他部分为空(并且不使用我的自定义序列化),删除了空值。 看起来像Newtonsoft序列化程序写入字符串生成器所以我们应该能够“回放”任何书面的json标记但我不知道如何不写任何东西。

什么都不做,只是返回导致序列化程序抛出exception,因为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 } 

NullValueHandling用于对象引用。 在您的示例中,您的值是一个整数。 要使用默认值省略整数属性,请使用设置DefaultValueHandling = DefaultValueHandling.Ignore

WriteJson()null检查不应该是必需的,因为Json.NET从不使用空值调用转换器。 相反,它会写入名称&null值本身 – 或者不是,如果NullValueHandling == NullValueHandling.Ignore 。 因此,永远不需要检查null和倒带。

如果其中一个转换器在WriteJson显式写入,则当空值处理或默认值处理为Ignore时,仍可能会写入对象属性的空值。 为了防止这种情况,您可以检查设置并跳过空值,如下所示:

 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; } }