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

Access already deserialized properties from JsonConverter.ReadJson

我正在尝试解决反序列化旧 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

的值

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

另一件事:在 WriteJson 方法中我想做 "nothing" 特殊的,我的实现是否正确?或者有没有一种简单的方法可以防止转换器在序列化时做任何事情"special"?

您需要将转换器应用到您的 parent A class:

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

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