在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))]
。
答案 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));
}