【发布时间】:2025-12-17 03:10:01
【问题描述】:
我有以下型号:
public interface IEntity
{
string Id { get; }
}
public class EntityParent : IEntity
{
public string Id { get; }
public EntityChild EntityChild { get; }
[JsonConstructor]
public EntityParent(string id, EntityChild entityChild)
{
Id = id;
EntityChild = entityChild;
}
}
public class EntityChild : IEntity
{
public string Id { get; }
public int Age { get; }
[JsonConstructor]
public EntityChild(string id, int age)
{
Id = id;
Age = age;
}
}
接下来我需要将一些 JSON 反序列化为上述类型的集合:
{
"Children":
[
{
"Id" : "Billy",
"Age" : 42
}
],
"Parents" :
[
{
"Id" : "William",
"EntityChild" : "Billy"
}
]
}
最终我想要一个EntityChildren 列表和一个EntityParents 列表,它们将(可选地)包含对第一个列表中对象的引用,或者至少包含对EntityChild 实例的引用。我试图编写一个自定义JsonConverter(我正在使用Newtonsoft.Json 9.0.1 NuGet 包),在ReadJson() 方法中我正在寻找一个具有特定Id 的孩子,像这样:
public class ParentConverter<TEntity> : JsonConverter where TEntity : IEntity
{
private readonly IEnumerable<TEntity> _children;
public ParentConverter(IEnumerable<TEntity> children)
{
_children = children;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
JObject jObject = JObject.Load(reader);
TEntity target = _children.FirstOrDefault(d => d.Id == jObject["Id"].ToString());
serializer.Populate(jObject.CreateReader(), target);
return target;
}
public override bool CanConvert(Type objectType)
{
return typeof(TEntity).IsAssignableFrom(objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
这是一个简单的测试:
public class JsonTest
{
const string Json = @"
{
""Children"": [
{
""Id"" : ""Billy"",
""Age"" : 42
}
],
""Parents"" : [
{
""Id"" : ""William"",
""EntityChild"" : ""Billy""
}
]
}";
public static void Main()
{
JObject jObject = JObject.Parse(Json);
var children =
JsonConvert.DeserializeObject<List<EntityChild>>(jObject["Children"].ToString());
var parents =
JsonConvert.DeserializeObject<List<EntityParent>>(jObject["Parents"].ToString(),
new ParentConverter<EntityChild>(children));
}
}
children 已正确反序列化,但 parents 在尝试在 ReadJson() 中调用 JObject.Load(reader); 时抛出 JsonReaderException,说“从 JsonReader 读取 JObject 时出错。当前 JsonReader 项不是对象:字符串。路径'[0].EntityChild'。"
有人知道我应该怎么做吗?提前致谢。
编辑:用额外的属性更新了EntityChild,以强调EntityParent 上的属性必须是EntityChild 类型,并且不是字符串。
【问题讨论】:
-
这个 JSON 结构是谁设计的?这很奇怪
-
@SirRufo 不幸的是它不在我的手中:(,而且不是我;)。
标签: c# json deserialization