我有以下情况(对于这个问题):
- 文档类
- 一个文档可以包含多种类型的多个项目
像这个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>();