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

时间:2014-03-03 11:02:52

标签: inheritance 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类型的实例。 Type是接口或抽象类,无法实例化。路径'项目[0] .name',第4行,第14位。

我尝试将TypeHandling属性添加到JsonProperty的{​​{1}}:

Items

但这产生了这个Json:

[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": [

我是否需要引入一个包含{ "items": [ { "$type": "UserQuery+ItemA, LINQPadQuery", "name": "Test Name" }, { "$type": "UserQuery+ItemB, LINQPadQuery", "value": 42 } ] } 类型的简单属性的包装器对象而不是该属性?

1 个答案:

答案 0 :(得分:2)

你很亲密。尝试使用ItemTypeNameHandling代替TypeNameHandling

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