Deserialize a List<AbstractClass> with newtonsoft.json
我正在尝试序列化和反序列化
我用
但是当我反序列化它时一直说他不能反序列化一个抽象类。
http://james.newtonking.com/json/help/index.html?topic=html/SerializeTypeNameHandling.htm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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; } } } |
删除注释行就可以了!
确保在反序列化时指定 TypeNameHandling,根据文档:
1 2 3 4 5 | // for security TypeNameHandling is required when deserializing Stockholder newStockholder = JsonConvert.DeserializeObject<Stockholder>(jsonTypeNameAuto, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); |
值得注意的是,文档正在反序列化一个包含抽象类集合的具体类。
作为一个实验,尝试创建一个一次性类(具体),该类具有一个包含抽象对象列表的单一属性,并查看是否可以对其进行序列化和反序列化。
更新:
我刚刚在 LINQPad 中测试了以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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;} } |
效果很好。抽象集合序列化为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | { "$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" } ] } |
匹配的原始和反序列化集合。