从 C# 程序中反序列化 JSON 时,我是不是需要使用 JavaScriptSerializer 以外的任何东西?

Posted

技术标签:

【中文标题】从 C# 程序中反序列化 JSON 时,我是不是需要使用 JavaScriptSerializer 以外的任何东西?【英文标题】:When deserializing JSON from within a C# program, should I ever need to use anything other than JavaScriptSerializer?从 C# 程序中反序列化 JSON 时,我是否需要使用 JavaScriptSerializer 以外的任何东西? 【发布时间】:2011-05-30 05:36:39 【问题描述】:

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

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

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

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


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

【问题讨论】:

【参考方案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。

希望这会有所帮助!

【讨论】:

Re #1,您正在寻找 JavaScriptSerializer 的 DeserializeObject() 方法而不是 Deserialize()。这很好,简单/灵活。 @Dave Ward:很好!我已经编辑了答案以反映这一点【参考方案2】:

我在各种各样的场景中使用 JavaScriptSerializer,它从来没有让我失望,也不需要在别处寻找其他解决方案...... :)

...但我知道 JSON.net 有一些附加值,例如 LINQ to JSON,这是我从来不需要的,以及不错的 JSON 格式,但随着序列化的进行,JavaScriptSerializer 可以正常工作。

【讨论】:

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

以上是关于从 C# 程序中反序列化 JSON 时,我是不是需要使用 JavaScriptSerializer 以外的任何东西?的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中序列化为 JSON 并在 TS 中反序列化

jQuery/ASMX:在 C# 中反序列化 JSON 时出错

[C#]如何使用Newton.Json从流中反序列化json数据

使用 LitJson 在 C# 中反序列化 JSON 对象数组 [重复]

在 C# 中反序列化 JSON 数组

无法在 C# 中反序列化 JSON 结果。输入字符串格式不正确错误