Json.NET和对象的集合,其中的对象是类层次结构的一部分



我有以下情况(对于这个问题):

  • 文档类
  • 一个文档可以包含多种类型的多个项目

像这个LINQPad程序:

void Main()
{
var doc = new Document();
doc.Items.Add(new ItemA { Name = "Test Name" });
doc.Items.Add(new ItemB { Value = 42 });
string json = JsonConvert.SerializeObject(doc, Newtonsoft.Json.Formatting.Indented).Dump();
JsonConvert.DeserializeObject<Document>(json).Dump();
}
[JsonObjectAttribute("doc")]
public class Document
{
[JsonProperty("items")]
public List<Item> Items = new List<Item>();
}
public abstract class Item { }
public class ItemA : Item
{
[JsonProperty("name")]
public string Name { get; set; }
}
public class ItemB : Item
{
[JsonProperty("value")]
public int Value { get; set; }
}

此程序在调用DeserializeObject:时出现此异常而失败

JsonSerializationException:无法创建类型为UserQuery+Item的实例。类型是接口或抽象类,不能实例化。路径"items[0].name",第4行,位置14。

我尝试将TypeHandling属性添加到Items:的JsonProperty

[JsonProperty("items", TypeNameHandling = TypeNameHandling.All)]
public List<Item> Items = new List<Item>();

但这就产生了Json:

{
"items": {
"$type": "System.Collections.Generic.List`1[[UserQuery+Item, LINQPadQuery]], mscorlib",
"$values": [

这不是我想要的,因为它指定了列表的类型,但不是每个项目的类型,但是我似乎不知道如果如何

通过这个我想要以下类型的Json:

{
"items": [
{
"$type": "UserQuery+ItemA, LINQPadQuery",
"name": "Test Name"
},
{
"$type": "UserQuery+ItemB, LINQPadQuery",
"value": 42
}
]
}

我是否需要引入一个具有Item类型的简单属性的包装器对象,而该属性处于启用状态?

你很接近。尝试使用ItemTypeNameHandling而不是TypeNameHandling:

[JsonProperty("items", ItemTypeNameHandling = TypeNameHandling.All)]
public List<Item> Items = new List<Item>();

最新更新