gpt4 book ai didi

c# - 没有 $refs 的 JsonConverter : Get parent object in ReadJson,

转载 作者:太空宇宙 更新时间:2023-11-03 10:29:18 24 4
gpt4 key购买 nike

我有一个 JSON 输入,其对象全部派生自基类,如下所示:

public abstract class Base
{
public Base Parent { get; set; }
}

我正在尝试创建一个 CustomCreationConverter 以使用 ReadJson 将每个对象的 Parent 属性设置为 JSON 输入中的父节点(当然根节点除外)。这可能吗?我宁愿不必在创建后遍历对象来设置 Parent 属性。

示例时间!

假设我有这个输入 JSON:

{
"Name": "Joe",
"Children": [
{ "Name": "Sam", "FavouriteToy": "Car" },
{ "Name": "Tom", "FavouriteToy": "Gun" },
]
}

我有以下两个类:

public class Person
{
public Person Parent { get; set; }
public string Name { get; set; }
public List<Child> Children { get; set; }
}

public class Child : Person
{
public string FavouriteToy { get; set; }
}

NameFavouriteToy 属性反序列化很好,但我想拥有任何 PersonParent 属性如您所料,对象设置为 JSON 输入中的实际父对象(大概使用 JsonConverter)。到目前为止,我能够实现的最佳效果是在反序列化后递归遍历每个对象并以这种方式设置 Parent 属性。

附言

我想指出,我知道我可以使用 JSON 本身内部的引用来做到这一点,但我宁愿避免这样做。

不是重复的:(

该问题涉及创建正确派生类的实例,我遇到的问题是在对象反序列化期间找到获取上下文的方法。我正在尝试使用 JsonConverter 的 ReadJson 方法设置反序列化对象的属性以引用同一 JSON 输入中的另一个对象,使用 $refs。

最佳答案

我最好的猜测是您正在寻找这样的东西:

public override bool CanConvert(Type objectType)
{
return typeof(Person).IsAssignableFrom(objectType);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
object value = Activator.CreateInstance(objectType);
serializer.Populate(reader, value);

Person p = value as Person;
if (p.Children != null)
{
foreach (Child child in p.Children)
{
child.Parent = p;
}
}
return value;
}

注意:如果您经常反序列化此类(例如从 Web 应用程序中的 http 请求反序列化模型),使用预编译工厂创建对象将获得更好的性能,而不是使用对象激活器:

object value = serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();

请注意,无法访问父对象,因为父对象总是其子对象之后创建。也就是说,您需要读取对象所包含的 json 直到最后才能完全构造对象,并且在读取对象的最后一个括号时,您已经读取了它的所有子对象。当一个 child 解析时,还没有 parent 获得引用。

关于c# - 没有 $refs 的 JsonConverter : Get parent object in ReadJson,,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30769476/

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