在JSON.NET中反序列化十进制值的自定义规则

时间:2018-08-16 21:00:23

标签: c# json json.net

每当有一个JsonConvert.DeserializeObject的属性具有一个JSON值时,使用nulldecimal数据转换为自定义类时,就会遇到问题。 / p>

我想实现一个自定义规则,该规则仅在我想使用时才使用-不需要全局设置。在这种特殊情况下,只要属性为十进制类型,我都希望null的值成为0

我如何做到这一点?

1 个答案:

答案 0 :(得分:1)

您可以在反序列化类型中使用批注,或者在反序列化时(而不是全局)指定自定义转换器/设置。我认为,仅处理 some decimal属性的唯一好方法是使用注释。

string json = @"{""val"": null}";

public class NoAnnotation {
    public decimal val {get; set;}
}

public class WithAnnotation {
    [JsonConverter(typeof(CustomDecimalNullConverter))]
    public decimal val {get; set;}
}

void Main()
{   
    // Converting a type that specifies the converter
    // with attributes works without additional setup
    JsonConvert.DeserializeObject(json, typeof(WithAnnotation));

    // Converting a POCO doesn't work without some sort of setup,
    // this would throw
    // JsonConvert.DeserializeObject(json, typeof(NoAnnotation));

    // You can specify which extra converters
    // to use for this specific operation.
    // Here, the converter will be used
    // for all decimal properties
    JsonConvert.DeserializeObject(json, typeof(NoAnnotation),
       new CustomDecimalNullConverter());

    // You can also create custom serializer settings.
    // This is a good idea if you need to serialize/deserialize multiple places in your application,
    // now you only have one place to configure additional converters
    var settings = new JsonSerializerSettings();
    settings.Converters.Add(new CustomDecimalNullConverter());
    JsonConvert.DeserializeObject(json, typeof(NoAnnotation), settings);
}

// For completeness: A stupid example converter
class CustomDecimalNullConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(decimal);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
        {
            return 0m;
        }
        else
        {
            return Convert.ToDecimal(reader.Value);
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteValue((decimal)value);
    }
}