根据对象的一个属性将对象序列化为null



在Newtonsoft Json中。. NET自定义JsonConverterWriteJson方法,我可以从JsonConverter中调用默认的对象序列化行为吗?

也就是说,如果没有注册自定义转换器,我可以推迟序列化吗?

详细信息

给定一个Price类

public class Price
{
    public string CurrencyCode;
    public decimal Amount;
}

正常的Newtonsoft Json。. NET行为是仅当引用为空时才将Price实例序列化为空。此外,我想在Price.Amount为零时将Price实例序列化为null。这是我到目前为止所做的工作(完整的源代码)

public class PriceConverter : JsonConverter 
{
    // ...
    public override void WriteJson(
        JsonWriter writer, 
        object value, 
        JsonSerializer serializer) 
    {
        var price = (Price)value;
        if (0 == price.Amount) {
            writer.WriteNull();
            return;
        }
        // I'd like to replace the rest of this method with an appeal to the 
        // default serialization behavior.
        writer.WriteStartObject();
        writer.WritePropertyName("amount");
        writer.WriteValue(price.Amount);
        writer.WritePropertyName("currencyCode");
        writer.WriteValue(price.CurrencyCode);
        writer.WriteEndObject();
    }
    // ...
}

这个实现的最后一部分是脆弱的。例如,如果我要向Price添加字段,我的序列化将被破坏(并且我不知道编写测试来检测这种破坏的好方法)。

我的序列化器有许多行为,通过JsonSerializerSettings在一个单独的程序集中配置,我需要保留这些行为(例如,骆驼大小写属性名)。我不可能在这两者之间添加直接依赖关系。实际上,我使用[JsonConverter(typeof(PriceConverter))]属性来指定我的自定义转换器应该用于Price

有一个解决方法可以让转换器接收设置——您可以使用序列化上下文。

设置:

var settings = new JsonSerializerSettings { /*...*/ };
settings.Context = new StreamingContext(StreamingContextStates.All, settings);
在转换器

:

var settings = (JsonSerializerSettings)serializer.Context.Context;

我做的时候感觉很脏

这种方法有什么问题?

public static JsonSerializerSettings MySettings()
{
    return new JsonSerializerSettings
        {
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
        TypeNameHandling = TypeNameHandling.All,
        DefaultValueHandling = DefaultValueHandling.Ignore,
        DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind,
        };
}

在你的PriceConverter:

if (0 == price.Amount)
{
    writer.WriteNull();
    return;
}
else
{
    writer.WriteRaw(JsonConvert.SerializeObject(value, Somewhere.MySettings()));
    return;
}

在你的程序中:

    public static void Custom(Price p)
    {
        var settings = Somewhere.MySettings();
        settings.Converters = new List<JsonConverter> { new PriceConverter() };
        Console.WriteLine("custom: " +
            JsonConvert.SerializeObject(p, settings));
    }

相关内容

  • 没有找到相关文章

最新更新