2

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

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

之前是:

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我想做“没什么”特别的方法中,我的实现是否正确?或者有没有一种简单的方法可以防止转换器在序列化时做任何“特殊”的事情?

4

1 回答 1

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

要使用默认的 serailisation,只需CanWrite覆盖false.

于 2020-01-31T12:01:26.083 回答