基于其中一个属性将对象序列化为null

时间:2013-06-05 19:41:12

标签: .net json serialization json.net

在Newtonsoft Json.NET自定义JsonConverter的{​​{1}}方法中,我是否可以在WriteJson范围内对默认对象序列化行为提出申诉?

也就是说,如果自定义转换器尚未注册,我可以推迟发生的序列化吗?

详细

给出价格等级

JsonConverter

正常的Newtonsoft Json.NET行为是仅在引用为null时将public class Price { public string CurrencyCode; public decimal Amount; } 实例序列化为null。此外,我想在Price为零时将Price个实例序列化为null。这是我到目前为止所做的工作(complete source code

Price.Amount

此实施的最后一部分是脆弱的。例如,如果我要将字段添加到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(); } // ... } ,我的序列化将被破坏(我不知道编写一个检测中断的测试的好方法。)

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

2 个答案:

答案 0 :(得分:2)

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

设置:

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

转换器:

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

我这样做时感觉很脏。

答案 1 :(得分:0)

这种方法有什么问题?

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