哪个Json反序列化器呈现IList 集合?
我正在尝试将json反序列化为对象模型,其中集合表示为IList
类型。
实际的反序列化在这里:
JavaScriptSerializer serializer = new JavaScriptSerializer(); return serializer.Deserialize<IList>( (new StreamReader(General.GetEmbeddedFile("Contacts.json")).ReadToEnd()));
在我发布exception之前,我知道你应该知道隐含的转换是什么。 这是Contact
类型:
public class Contact { public int ID { get; set; } public string Name { get; set; } public LazyList Details { get; set; } //public List Details { get; set; } }
这是ContactDetail
类型:
public class ContactDetail { public int ID { get; set; } public int OrderIndex { get; set; } public string Name { get; set; } public string Value { get; set; } }
使用LazyList
要知道的重要一点是它实现了IList
:
public class LazyList : IList { private IQueryable _query = null; private IList _inner = null; private int? _iqueryableCountCache = null; public LazyList() { this._inner = new List(); } public LazyList(IList inner) { this._inner = inner; } public LazyList(IQueryable query) { if (query == null) throw new ArgumentNullException(); this._query = query; }
现在这个LazyList
类定义很好,直到我尝试将Json反序列化为它。 System.Web.Script.Serialization.JavaScriptSerializer
似乎想要将列表序列化为List
,这对于它的年龄有意义,但我需要它们在IList
类型中,所以它们将被LazyList
转换为我的LazyList
(至少那是我认为我出错的地方)。
我得到这个例外:
System.ArgumentException: Object of type 'System.Collections.Generic.List`1[ContactDetail]' cannot be converted to type 'LazyList`1[ContactDetail]'..
当我尝试在我的Contact
类型中使用List
时(如上所述),它似乎有效。 但我不想使用List
。 我甚至尝试从List
LazyList
inheritance我的LazyList
似乎执行但是将List
的内部T[]
传递给我的实现是一场噩梦,我根本不想要List
的膨胀List
我的模特中的任何地方。
我也尝试了其他一些json库无济于事(我可能没有充分利用它们。我或多或少地替换了引用并试图重复这个问题顶部引用的代码。也许传递设置参数将会救命??)。
我现在不知道该尝试什么。 我和另一个解串器一起去吗? 我是否会调整反序列化本身? 我需要更改我的类型以取悦反序列化器吗? 我是否需要更多担心隐式转换或只是实现另一个接口?
不可能直接反序列化到接口,因为接口只是一个契约。 JavaScriptSerializer必须反序列化为实现IList
var list = serializer.Deserialize>(...); var lazyList = new LazyList(list);
不幸的是,您可能需要修复您的类,因为反序列化器无法知道它应该是IList类型,因为List是IList的实现。
由于http://json.org上的反序列化器具有可用的源代码,因此您只需修改一个即可完成所需的操作。
我最终使用了Json.NET lib ,它对自定义映射有很好的linq支持。 这就是我的反序列化最终看起来像:
JArray json = JArray.Parse( (new StreamReader(General.GetEmbeddedFile("Contacts.json")).ReadToEnd())); IList tempContacts = (from c in json select new Contact { ID = (int)c["ID"], Name = (string)c["Name"], Details = new LazyList( ( from cd in c["Details"] select new ContactDetail { ID = (int)cd["ID"], OrderIndex = (int)cd["OrderIndex"], Name = (string)cd["Name"], Value = (string)cd["Value"] } ).AsQueryable()), Updated = (DateTime)c["Updated"] }).ToList(); return tempContacts;