簡體   English   中英

反序列化派生類時如何忽略基類JsonConverter?

[英]How to ignore base class JsonConverter when deserializing derived classes?

我有一個抽象基類:

[JsonConverter(typeof(Converter))]
public abstract class TextComponent {
    ...
    public bool Bold { get; set; }
    public TextComponent[] Extra { get; set; }
    ...
}

還有更多繼承自它的類。 這些類之一是StringComponent

public sealed class StringComponent : TextComponent
{
    public string Text { get; set; }

    public StringComponent(string text)
    {
        Text = text;
    }
}

Converter ,它是應用於TextComponentJsonConverter ,如下所示:

private sealed class Converter : JsonConverter
{
    ....

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
        JsonSerializer serializer)
    {
        var tok = JToken.Load(reader);
        switch (tok)
        {
            ...
            case JObject x:
                var dic = (IDictionary<string, JToken>) x;
                if (dic.ContainsKey("text")) return x.ToObject<StringComponent>();
                ...
            ...
        }
    }
    ...
    public override bool CanConvert(Type objectType) => objectType == typeof(TextComponent);
}

問題

var str = "{\"text\":\"hello world\"}";
var obj = JsonConvert.DeserializeObject<TextComponent>(str);
// this doesn't work either:
var obj = JsonConvert.DeserializeObject<StringComponent>(str);

這會進入無限的“循環”,最終導致StackOverflow ,因為調用DeserializeObject<Stringcomponent>ToObject<StringComponent> ,將使用基類的JsonConverterConverter ),該類再次調用這些方法。 這不是所需的行為。 序列化派生類時,不應使用基類的JsonConverter 如果您查看Converter CanConvert方法,那么我也只允許它用於TextComponent ,而不允許它用於任何派生類。

那么我該如何解決呢?

您可以將子類合約上的轉換器設置為null;

    public override bool CanWrite => false;
    public override bool CanRead => true;

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (objectType == typeof(BaseClass))
        {
            JObject item = JObject.Load(reader);
            if (item["isClass2"].Value<bool>())
            {
                return item.ToObject<ChildClass2>(serializer);
            }
            else
            {
                return item.ToObject<ChildClass1>(serializer);
            }
        }
        else
        {
            serializer.ContractResolver.ResolveContract(objectType).Converter = null;
            return serializer.Deserialize(reader, objectType);
        }
    }

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

您是否嘗試從基類中刪除[JsonConvert]屬性? 在我的示例中,我手動調用了“自定義”轉換器: https : //github.com/Code-Inside/Samples/blob/b635580a4966b1b77c93a8b682389c6cf06d2da6/2015/JsonConvertIssuesWithBaseClasses/JsonConvertIssuesWithBaseClasses/Program.cs#L36-L79

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM