哪个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 LazyListinheritance我的LazyList似乎执行但是将List的内部T[]传递给我的实现是一场噩梦,我根本不想要List的膨胀List我的模特中的任何地方。

我也尝试了其他一些json库无济于事(我可能没有充分利用它们。我或多或少地替换了引用并试图重复这个问题顶部引用的代码。也许传递设置参数将会救命??)。

我现在不知道该尝试什么。 我和另一个解串器一起去吗? 我是否会调整反序列化本身? 我需要更改我的类型以取悦反序列化器吗? 我是否需要更多担心隐式转换或只是实现另一个接口?

不可能直接反序列化到接口,因为接口只是一个契约。 JavaScriptSerializer必须反序列化为实现IList 的某种具体类型,最合理的选择是List 。 您必须将List转换为LazyList,它给出了您发布的代码,应该很容易:

 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;