NullValueHandling.Ignore与JsonConverter :: WriteJson

时间:2015-10-20 15:43:30

标签: c# json json.net

我正在尝试执行自定义序列化,所有快乐路径代码都可以正常工作但空值路径的行为并不像我想的那样。

我已将序列化程序设置设置为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 个答案:

答案 0 :(得分:3)

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

null签入WriteJson()不是必需的,因为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; }
}