gpt4 book ai didi

c# - 使用 JsonConverterAttribute 时自定义继承 JsonConverter 失败

转载 作者:行者123 更新时间:2023-11-30 14:10:08 25 4
gpt4 key购买 nike

我正在尝试反序列化派生类型,并且我想使用自定义属性 Type区分派(dispatch)生类型。

[
{
"Type": "a",
"Height": 100
},
{
"Type": "b",
"Name": "Joe"
}
]

我想到的解决方案是创建自定义 JsonConverter .在 ReadJson我读了Type属性并通过 ToObject<T> 实例化该类型功能。在我使用 JsonConverterAttribute 之前一切正常. ReadJson方法无限循环,因为该属性也应用于子类型。

如何防止将此属性应用于子类型?

[JsonConverter(typeof(TypeSerializer))]
public abstract class Base
{
private readonly string type;

public Base(string type)
{
this.type = type;
}

public string Type { get { return type; } }
}

public class AType : Base
{
private readonly int height;

public AType(int height)
: base("a")
{
this.height = height;
}

public int Height { get { return height; } }
}

public class BType : Base
{
private readonly string name;

public BType(string name)
: base("b")
{
this.name = name;
}

public string Name { get { return name; } }
}

public class TypeSerializer : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Base);
}

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

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

var type = j["Type"].ToObject<string>();

if (type == "a")
// Infinite Loop! StackOverflowException
return j.ToObject<AType>();
if (type == "b")
return j.ToObject<BType>();

throw new NotImplementedException(type);
}
}

[TestFixture]
public class InheritanceSerializeTests
{
[Test]
public void Deserialize()
{
var json = @"{""Type"":""a"", ""Height"":100}";
JObject.Parse(json).ToObject<Base>(); // Crash
}
}

最佳答案

我目前正在处理的一个项目遇到了一个非常相似的问题:我想制作一个自定义的 JsonConverter 并通过属性将其映射到我的实体,但随后代码陷入了无限循环。

在我的案例中,诀窍是使用 serializer.Populate 而不是 JObject.ToObject (我什至不能使用 .ToObject如果我愿意的话;我使用的是 3.5.8 版,其中不存在此功能)。下面以我的 ReadJson 方法为例:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JContainer lJContainer = default(JContainer);

if (reader.TokenType == JsonToken.StartObject)
{
lJContainer = JObject.Load(reader);
existingValue = Convert.ChangeType(existingValue, objectType);
existingValue = Activator.CreateInstance(objectType);

serializer.Populate(lJContainer.CreateReader(), existingValue);
}

return existingValue;
}

关于c# - 使用 JsonConverterAttribute 时自定义继承 JsonConverter 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25404202/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com