DataContractJsonSerializer与JavaScriptSerializer的内部实现差异

问题的引子

先来看问题的引子。

定义一个下面这样的类,此类有Serializable属性,并且有一个属性的定义没有使用自动属性来实现。

[Serializable]
 public class Users
 {
     public int UserID { get; set; }

     public string UserName { get; set; }

     public string UserEmail { get; set; }

     private string _testProperty;
     public string TestProperty
     {
         get { return _testProperty; }
         set { _testProperty = value; }
     }
 }

然后分别使用DataContractJsonSerializer和JavaScriptSerializer对此对象的示例进行序列化。

使用DataContractJsonSerializer序列化后的结果。

{"_testProperty":"TestPropertyValue","<UserEmail>k__BackingField":"parry@cnblogs.com",
"<UserID>k__BackingField":1,"<UserName>k__BackingField":"Parry"}

使用JavaScriptSerializer序列化后的结果。

{"UserID":1,"UserName":"Parry","UserEmail":"parry@cnblogs.com","TestProperty":"TestPropertyValue"}

DataContractJsonSerializer和JavaScriptSerializer的实现差异

DataContractJsonSerializer在.NET Framework 3.5中引入,主要因为WCF的引入而添加了这个对象序列化的基本方法,并且微软同时将JavaScriptSerializer打上了过时(obsolete)的标签,编译时就会有警告出现。

而在.NET Framework 3.5 SP1中,微软又将JavaScriptSerializer的“过时”标签给去掉了。

使用Reflector去比较这两个类的内部实现发现,DataContractJsonSerializer在对象序列化时进行了更为严格的检查,感兴趣的可以去System.Runtime.Serialization.Json下面的核心方法InternalWriteObjectContent去看其实现。

而在.NET Framework 3.5引入的自动属性,实际上就是个语法糖,编译器还是会生成一个int类型的<Name>k_BackingField的私有字段作为这个属性的后端字段,内部还是和以前的get/set方法一样。

所以直接使用DataContractJsonSerializer进行序列化时,又将编译器生成的k_BackingField带了出来。

而JavaScriptSerializer的实现则非常简单,将属性名和属性值分别存储在Dictionary里,然后进行字符串拼接返回而已,所以对类定义几乎没有检查并且对复杂类的支持不太好。

下面是JavaScriptSerializer里面的核心方法SerializeValue的实现。

private void SerializeValue(object o, StringBuilder sb, int depth, Hashtable objectsInUse,
 SerializationFormat serializationFormat, MemberInfo currentMember = null) {
     if (++depth > _recursionLimit) {
         throw new ArgumentException(AtlasWeb.JSON_DepthLimitExceeded);
     }

     // Check whether a custom converter is available for this type.
     JavaScriptConverter converter = null;
     if (o != null && ConverterExistsForType(o.GetType(), out converter)) {
         IDictionary<string, object> dict = converter.Serialize(o, this); 

         if (TypeResolver != null) {
             string typeString = TypeResolver.ResolveTypeId(o.GetType());
             if (typeString != null) {
                 dict[ServerTypeFieldName] = typeString;
             }
         }

         sb.Append(Serialize(dict, serializationFormat));
         return;
     } 

     SerializeValueInternal(o, sb, depth, objectsInUse, serializationFormat, currentMember);
 }

解决方法

如果一定要使用DataContractJsonSerializer,只有当为类加上[DataContract]属性,并且为需要序列化的属性加上[DataMember]后,使用DataContractJsonSerializer才可以生成干净、整洁的JSON数据。

而当我们使用一些不能修改的类定义,如上面的Users类定义,我们没有权限去修改其定义,那么就可以使用JavaScriptSerializer去进行JSON序列化。

当然第三方的Json.NET(Newtonsoft.Json)也是可以实现的,并且在支持的功能和效率方面往往是一个更好的选择,在这里看它和DataContractJsonSerializer以及JavaScriptSerializer的使用对比。

所以在使用时需要稍微注意下这三个JSON序列化方法的差异,根据自己的需求灵活选择合适的组件。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索string
, 方法
, 属性
, public
javascriptserializer
javascriptserializer、jsonserializer、jsonserializer使用、jsonserializer 用法、c jsonserializer,以便于您获取更多的相关知识。

时间: 2024-10-29 09:16:20

DataContractJsonSerializer与JavaScriptSerializer的内部实现差异的相关文章

关于Runtime.getRuntime().exec 在windows和linux下运行的差异

问题描述 本人使用runtime类执行备份数据库的任务,分别在windows和linux环境下测试都能执行,windows下output会打印脚本出来而linux下output没有打印.如果注释掉两个线程,windows下会发生阻塞,主线程一直运行,linux下不会阻塞,线程正常结束.请问各位仁兄谁知道它内部的差异的原因?谢谢!核心代码如下:process=Runtime.getRuntime().exec("/opt/backup.sh");Threadesg=newStreamGo

大数据告诉你要不要当公务员?

大清早,学姐就推开我寝室的门,说道:"我妈又打电话催我要准备国考了." 没错,这就是最近学姐和我之间的主要话题.什么考公务员考到哪里啦,公务员工资高不高啦,工作是不是很轻松啦.其实我觉得这些都不是什么重要因素.收入?轻松?还要考虑这些事?难道当一名光荣的公务员的主要原因不应当是希望自己能够鞠躬尽瘁死而后已地致力于为人民服务的伟大事业吗? 当然,这些话我并未出口,大清早的我实在不想再被学姐打了.但为了结束这个絮絮叨叨的话题,我还是决定帮助她研究这么一个小问题: 学姐啊,公务员收入什么的我

关于DateTime对象序列化为Json之后的若干问题

将Datetime对象序列化成Json对象是常有的事情,微软的序列化方法会将Datetime对象序列化成一个字符串: "\/Date(1234656000000)\/" 这样的字符串相当之不友好,但微软貌似喜欢,并且Json.net在4.5之前也是这么做的.现在的Json.net在序列化的时候,会将其转换为ISO标准时间: "2009-02-15T00:00:00Z" 在使用Json.net的时候,我们还可以使用其默认的DateTime转换器来处理,这样转换的字符串

Json.Net6.0入门学习试水篇

原文:Json.Net6.0入门学习试水篇 前言 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.简单地说,JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 Web 客户机传递给服务器端程序.这个字符串看起来有点儿古怪,但是 JavaScript 很容易解释它,而且 JSON 可以表示比"名称 / 值对"更复杂的结构.例如,可以表示数组和复杂的

分好社会财富这个蛋糕

方向新,1956年生,湖南省湘潭县人.现任湖南省社科院副巡视员,教授.主要从事应用社会学研究,其研究领域包括城乡社会学.人口社会学.经济社会学.组织社会学以及人民内部矛盾问题研究等.主持完成国家级和省部级课题多项,出版专著30余部,公开发表论文240余篇.先后获得湖南省优秀中青年专家.湖南省首届优秀青年社会科学专家等荣誉称号. 采访日志2月27日多云湖南省社科院 人物簿 存档号:NO.026 正在进行的全国"两会"传出的诸多信号,让老百姓对于收入分配体制改革有了更多的期待.有人将收入分

中国家族企业真面目

传统的中国家族企业常常严守中国的商业价值传统,不愿对外公布信息,谨遵财不露白.家丑不外扬的原则,造成认识这些企业的信息壁垒 文/李刚 邱静 近三十年来,中国家族企业发展壮大,成为私营部门的生力军,在促进经济发展.解决就业等社会问题方面起到关键作用.受中国独特的传统文化和近现代社会制度变迁影响,中国家族企业呈现出明显的中国特色,而这些特色常常被忽略. 家族企业在中国的历史源远流长.明清时代涌现出的各地"商帮",大都建立在家族.宗族的基础之上.如著名的晋商.徽商.浙商等,其内部通常沿袭中国

高铁改变中国经济地势

"高铁"建设正在贯通中国经济的"血脉",进而改变中国传统区域经济的格局. <商业价值>杂志 赵鑫|文 中国和世界各国的经济发展规律告诉我们,交通基础设施的供应水平和能力必须适度超前,否则就会影响社会经济持续.稳定和健康发展.据世界主要发达国家的资料分析,当人均GDP从1000美元上升到3000美元时,居民主要消费结构就会发生较大变化,用于交通和通信消费支出的平均比重将稳步上升,从8%-9%上升到11%-12%.中国现有总人口已超过13亿,预测到2020年

云计算时代:通过能耗看信息管理系统

IT工程师很少从熵的角度来设计一个系统.事实上其它领域的工程师在设计创建一个新系统的时候,似乎也没有考虑熵的因素.造成这种想象的可能存在资本市场体制.能源以及对熵的认识程度等问题. 目前人们并不担心能源问题,他们相信在他们关心的时间内,可以为这些产品提供足够的外部能源.比如汽车厂商,他们相信现在的石油可以保证他们生产的产品正常销售. 在自私的资本市场体制下,人们只需要关心产品带来的财富,而不需要关心对社会造成的负面危害.比如苹果公司只关心产品可以赚多少钱,不会考虑会造成人类生存系统熵增加的后果(

巧搭年度预算七孔桥

又到年底预算时. 先不妨从枯燥的预算报表中移开目光,试试看其他领域是否有他山之石的智慧.经过<首席财务官>杂志编辑部的多次讨论,大家一致认为"桥"是一个非常好的借代物,来象征跨越公司财务资源和运营体系两岸的预算方案.众所周知,以赵州桥为代表的石拱桥为中国古代建筑艺术赢得了世界性的赞誉.这座建于隋朝公元605年至618年的普通石桥,由当时无籍籍之名的石匠李春所建,历时1350多年的沧桑,安度无数次洪水冲击乃至八次地震的考验,巍然挺立在清水河上. 来吧,让我们试试用建造石拱桥的