vb.net 使用 newtonsoft.json 反序列化 List<AbstractClass>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20038441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 15:51:49  来源:igfitidea点击:

Deserialize a List<AbstractClass> with newtonsoft.json

c#.netvb.netserializationjson.net

提问by L.Trabacchin

i'm trying to serialize and deserialize a list of abstractclasses (mustinheritfor vb), obviusly inside it there are only instances of derived classes.

我正在尝试序列化和反序列化一个abstract类列表(mustinherit对于 vb),显然其中只有派生类的实例。

I've decorated the list parameter with the JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto)obtaining an output that look like this:

我已经使用JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto)获取如下所示的输出来修饰列表参数:

But when i deserialize it keep saying that he cannot deserialize an abstract class.

但是当我反序列化时,它一直说他不能反序列化一个抽象类。

http://james.newtonking.com/json/help/index.html?topic=html/SerializeTypeNameHandling.htm

http://james.newtonking.com/json/help/index.html?topic=html/SerializeTypeNameHandling.htm

public class ConcreteClass
{
    private ObservableCollection<AbstractClass> _Nodes = new ObservableCollection<AbstractClass>();
    //<Newtonsoft.Json.JsonProperty(itemtypenamehandling:=Newtonsoft.Json.TypeNameHandling.Auto)>
    public ObservableCollection<AbstractClass> Nodes {
        get { return this._Nodes; }
    }
    public string Name { get; set; }
    public int Id { get; set; }
}

public abstract class AbstractClass
{
    private ObservableCollection<AbstractClass> _Nodes = new ObservableCollection<AbstractClass>();
    [Newtonsoft.Json.JsonProperty(itemtypenamehandling = Newtonsoft.Json.TypeNameHandling.Auto)]
    public ObservableCollection<AbstractClass> Nodes {
        get { return this._Nodes; }
    }
}

removing the commented line it works!

删除注释行它有效!

回答by Timothy Walters

Make sure you specify TypeNameHandling when deserializing, as per the docs:

根据文档,请确保在反序列化时指定 TypeNameHandling:

// for security TypeNameHandling is required when deserializing
Stockholder newStockholder = JsonConvert.DeserializeObject<Stockholder>(jsonTypeNameAuto, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto
});

It is worth noting that the documentation is deserializing a Concrete class that containsa collection of Abstract classes.

值得注意的是,该文档正在反序列化一个包含抽象类集合的Concrete类。

As an experiment try creating a throw-away class (concrete) that has a single property with your list of abstract objects and see if you can serialize and deserialize that.

作为实验,尝试创建一个一次性类(具体),该类具有带有抽象对象列表的单个属性,并查看是否可以对其进行序列化和反序列化。

UPDATE:

更新:

I just tested the following code in LINQPad:

我刚刚在 LINQPad 中测试了以下代码:

void Main()
{
    var test = new List<Business>();
    test.Add(new Hotel { Name = "Hilton", Stars = 5 });
    test.Add(new Pool { Name = "Big Splash", Capacity = 500 });

    test.Dump();

    string json = JsonConvert.SerializeObject(test, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.All
    });

    json.Dump();

    var businesses = JsonConvert.DeserializeObject<List<Business>>(json, new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.All
    });

    businesses.Dump();
}

// Define other methods and classes here
public abstract class Business
{
    public string Name { get;set; }
}
public class Hotel : Business
{
    public int Stars { get;set; }
}
public class Pool : Business
{
    public int Capacity { get;set;}
}

It worked perfectly. Abstract collection serialized to:

它工作得很好。抽象集合序列化为:

{
  "$type": "System.Collections.Generic.List`1[[UserQuery+Business, query_jvrdcu]], mscorlib",
  "$values": [
    {
      "$type": "UserQuery+Hotel, query_jvrdcu",
      "Stars": 5,
      "Name": "Hilton"
    },
    {
      "$type": "UserQuery+Pool, query_jvrdcu",
      "Capacity": 500,
      "Name": "Big Splash"
    }
  ]
}

The original and the deserialized collections matched.

原始集合和反序列化集合匹配。