4

在 Newtonsoft Json.NET customJsonConverterWriteJson方法中,我可以从内部上诉默认对象序列化行为JsonConverter吗?

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

细节

给定一个价格类

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

正常的 Newtonsoft Json.NET 行为是Price仅当引用为空时才将实例序列化为空。此外,我想将Price实例序列化为 null 任何时候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();
    }

    // ...
}

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

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

4

2 回答 2

2

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

设置:

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

在转换器中:

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

虽然我这样做的时候感觉很脏。

于 2013-06-07T06:05:44.347 回答
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));
    }
于 2013-06-05T20:23:26.353 回答