从JsonConverter.ReadJson访问已反序列化的属性

时间:2020-01-31 11:47:34

标签: c# json.net jsonconverter

我在反序列化旧json时试图解决向后兼容性。以前有double个属性,现在已更改为自定义类型。

我的想法是阅读double并简单地使用自定义json转换器将其转换。

之前为:

public class A
{
    [JsonProperty)]
    string Name { get; set; }
    [JsonProperty)]
    double Value { get; set; }
}

序列化为

{"Name":"test","Value":33.0}

新的:

public class A
{
    [JsonProperty]
    [JsonConverter(typeof(MyJsonConverter))]
    public MyType Value { get; set; }
}

序列化为

{"Value":{"Value":33.0,"Name":"test", ...}},

转换器:

public class MyJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType) => true;

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.Value is double value)
            return new MyType(value, ???); // here is the problem, I need Name value here
        return reader.Value;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) =>
        JToken.FromObject(value).WriteTo(writer);
}

但是要构造MyType,我需要一个字符串参数,它是另一个属性Name的值

如何从Name的转换器访问Value的值?如何访问已反序列化的内容?有树吗?令牌树?

另一件事:在WriteJson方法中,我想做的“没什么”,我的实现正确吗?还是有一种简单的方法来防止转换器在序列化时做任何“特殊”的事情?

1 个答案:

答案 0 :(得分:1)

您需要将转换器应用于您的父A类:

[JsonConverter(typeof(MyJsonConverter))]
public class A
{
    public MyType Value { get; set; }
}

public class AConverter : JsonConverter
{
    public override bool CanConvert(Type objectType) => objectType == typeof(A);

    public override bool CanWrite => false;

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jObject = JObject.Load(reader);

        // Check if the keys contains "Name"
        string name = jObject["Name"]?.ToString();

        var a = new A();

        if (name != null)
        {
            a.Value = new MyType
            {
                Name = name,
                Value = jObject["Value"].Value<double>()
            };
        }
        else
        {
            a.Value = jObject["Value"].ToObject<MyType>();
        }

        return a;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

要使用默认的序列化,只需用CanWrite覆盖false

相关问题