在C#程序中反序列化JSON时,除了JavaScriptSerializer,我是否需要使用其他工具?

8
.NET提供了System.Web.Script.Serialization命名空间中的JavaScriptSerializer类。(存在于System.Web.Extensions.dll中)
它最初旨在支持AJAX Web服务器应用程序,但是该类可被任何序列化和反序列化.NET类到JSON的应用程序(客户端、服务器、混合等)使用。我有一个桌面应用程序,可以捕获屏幕截图并上传到Facebook,使用此类来反序列化响应。
我是否需要在.NET内部寻找其他JSON反序列化工具?
如果是这样,为什么?在哪里可以找到?
如果不是,那么为什么会有JSON.Net存在?它严格来说只是为了历史目的吗? (即因为它是由社区在JavaScriptSerializer之前创建的)。
2个回答

1
在我的情况下,有各种原因阻止我使用JavaScriptSerializer。以下是其中的一些原因。
1)处理匿名类型时,反序列化效果不佳。
(删除线) 虽然对于序列化而言使用相当直截了当:
JavaScriptSerializer serializer = new JavaScriptSerializer(); 
String json = serializer.Serialize(data); 

然而,对于反序列化来说,有一个小烦恼,即反序列化器会接受一个泛型类型以及内容:

serializer.Deserialize<T>(String s) 

如果类型T在编译时未知且需要动态生成,则可能会出现问题。解决方法有点丑陋,因为它使用反射来创建通用方法(但它有效)。

var result = typeof(JavaScriptSerializer).GetMethod("Deserialize") 
             .MakeGenericMethod(JsonDataType) 
             .Invoke(serializer, new object[] { inputContent }); 

请注意:根据Dave Ward在这个答案中的评论,有一个DeserializeObject()可以用来预防此问题。

2)无法处理循环引用

我曾经遇到过这种情况,使用Entity Framework、Linq to SQL、NHibernate、NetTiers,甚至使用Castle's proxy时也会出现。根据MS Connect,当导航关系是双向的(可以访问关系的两个方向)时,将抛出循环引用异常,因此第一件事是禁用关系的一侧。同时,在使用1:1关系(或1:0..1或任何导致创建EntityReference类型属性的关系)时,也会抛出异常,这种情况下的异常将是System.Data.Metadata.Edm.AssociationType类型。

解决方法是使序列化程序忽略类型为EntityReference的属性,使用从JavaScriptConverter派生的空实现类,并使用JavaScriptSerializer对象的RegisterConverters方法进行注册。

3) 导致代码难以测试的有用功能

JavaScriptSerializer的一个有用功能是,您还可以实现自定义JavaScriptConverter并将其传递给JavaScriptSerializer以对序列化/反序列化进行细粒度控制。但是,要使其真正有用,您需要在编译时知道类型并具有对这些类型的引用。这实际上限制了此功能的有用性,因为通过引用这些类,您的代码变得紧密耦合,因此无法轻松地在诸如MVC过滤器之类的东西中使用它。

出于这些原因,我经常使用Json.NET。

希望这有所帮助!


1
关于#1,你应该使用JavaScriptSerializer的DeserializeObject()方法而不是Deserialize()。它非常简单易用/灵活。 - Dave Ward
@Dave Ward:干得好!我已经编辑了答案以反映这一点。 - Lorenzo

1

我在许多情况下都使用JavaScriptSerializer,它从未让我失望,并且从未需要寻找其他解决方案... :)

...但我知道JSON.net具有一些附加值,例如LINQ to JSON,这是我从未需要的,以及漂亮的JSON格式化,但就序列化而言,JavaScriptSerializer可以很好地完成工作。


如果我已经有了LINQ to Objects,那么“LINQ to JSON”会给我什么?它是否只反序列化我选择的字段? - Cheeso
1
他正在谈论 API LINQ to Json http://james.newtonking.com/archive/2008/02/11/linq-to-json-beta.aspx - kenny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接