在C#程序中反序列化JSON时,我是否需要使用除JavaScriptSerializer之外的任何东西?

Che*_*eso 8 .net c# serialization json

.NET在System.Web.Script.Serialization命名空间中提供JavaScriptSerializer类.(在System.Web.Extensions.dll中提供)

它最初旨在支持AJAX Web服务器应用程序,但该类可以被任何应用程序(客户端,服务器,混合,任何)使用,它们将.NET类序列化和反序列化为JSON.我有一个桌面应用程序,可以捕获屏幕截图并上传到Facebook,并使用此类来反序列化响应.

我是否想在其他地方寻找.NET内的JSON反序列化?

如果是这样,为什么?我会在哪里看?


如果没有,那为什么JSON.Net存在?它是否严格用于历史目的?(即,因为它是由JavaScriptSerializer之前的社区创建的).

Lor*_*nzo 1

就我而言,有多种原因阻止我使用JavaScriptSerializer。这里是其中的一些。

1)处理匿名类型时丑陋的反序列化

虽然序列化的用法相当简单:

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
String json = serializer.Serialize(data); 
Run Code Online (Sandbox Code Playgroud)

然而,对于反序列化,有一个小麻烦,因为反序列化器接受泛型类型以及内容:

serializer.Deserialize<T>(String s) 
Run Code Online (Sandbox Code Playgroud)

如果类型 T 在编译时未知并且需要是动态的,这可能会出现问题。据我了解,解决方法有点难看,因为它使用反射来创建通用方法(但它有效)

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

请注意:根据戴夫·沃德对此答案的评论,有一个DeserializeObject()可以用来防止这种情况。

2)无法处理循环引用

我在使用Entity Framework、Linq to SQL、NHibernate、NetTiers 甚至使用Castle 的代理时都看到过这种情况。

根据MS Connect,当可导航关系是双面的(可以访问关系的两侧)时,将引发循环引用异常,因此首先要做的是禁用关系的一侧。当您使用 1:1 关系(或 1:0..1 或导致创建 EntityReference 类型属性的任何关系)时,也会引发异常,在这种情况下,异常的类型为System.Data.Metadata.Edm.AssociationType

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

3)有用的功能导致代码的可测试性较差

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

由于这些原因,我经常最终使用 Json.NET。

希望这可以帮助!