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":,
"<UserName>k__BackingField":"Parry"
}
使用JavaScriptSerializer序列化后的结果。
{
"UserID":,
"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序列化方法的差异,根据自己的需求灵活选择合适的组件。
DataContractJsonSerializer和JavaScriptSerializer内部实现差异的更多相关文章
- Silverlight和WPF中DataContractJsonSerializer对时间的处理差异
原创文章转载请注明出处:@协思, http://zeeman.cnblogs.com Silverlight脱胎于WPF,他们的行为不完全并不完全相同,DataContractJsonSerializ ...
- StringUtil内部方法差异
StringUtil 的 isBlank.isEmply.isNotEmpty.isNotBlank 区别 String.trim()方法: trim()是去掉首尾空格 append(Stri ...
- .net core 对象序列化为Json及Json反序列化关于DataContractJsonSerializer和Newtonsoft使用的完整案例,源码已更新至开源模板
很多人告诉你怎么用,但是却不会告诉你用什么好.不知道在进行序列化和反序列化Json时用那个好,因为有太多选择,如.NET Framework下可以选DataContractJsonSerializer ...
- C# - Common Tool
Json 涉及命名空间 using System.IO; using System.Net; using System.Runtime.Serialization.Json; using Newton ...
- monads-are-elephants(转)
介绍monads有点像互联网时代的家庭手工业.我想 “为什么要反对传统?”,但这篇文章将以Scala对待monads的方式来描述. 有个古老的寓言,讲述了几个瞎子第一次摸到大象.一个抱着大象的腿说:“ ...
- Notes on 'Efficient Graph-Based Image Segmentation'
Notes on Efficient Graph-Based Image Segmentation 算法的目标 按照一种确定的标准, 将图片分割成细粒度的语义区域, 即Super pixel. 算法步 ...
- 【winform 学习】C# 转换成JSON对象
C#里面对json的处理有2种,JavaScriptSerializer和DataContractJsonSerializer. JavaScriptSerializer读出来就是key-value ...
- [Json.net]快速入门
引言 有个朋友问了一个如何更方便的解析json格式字符串,之前也没怎么研究过json.net,就上网帮他查了一下,现学现卖的给他整了一个demo,这才发现json.net的强大,用着很方便. Json ...
- Json.Net6.0入门学习试水篇
原文:Json.Net6.0入门学习试水篇 前言 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.简单地说,JSON 可以将 JavaScript 对象中 ...
随机推荐
- [iOS微博项目 - 2.3] - 用户取消对app的授权
github: https://github.com/hellovoidworld/HVWWeibo A.用户取消对app的授权 用户可以在微博网站上取消对某个应用(app)的授权 1.打开& ...
- ucenter同步登陆机制
有个ucenter可以用来实现多个站点同时登陆同时退出,用户同步的功能. 首先站点都要引入一个uc_client这样一个客户端,以登陆为例,登陆时首先会调用一个外部函数,uc_client/clien ...
- sqlservice 查询该字段的值是否为数字、不包含a-z字母、获取中文的首字母
select zjm from xskh where guid_yw='e6ee44f3-98ab-4446-bd9b-db2e525d3b24' and zjm not like '%[ABCDE ...
- android 拨打电话小功能
1.其实就是对Intent 的ACTION进行参数设置. 在manifest中药设置打电话的权限: <uses-permission android:name="android.per ...
- CString 转 char*; wstring 转 string
1. CString 转 char* ); CString name; name.Format(_T("bookUC%d.txt"),m_ID); std::wstring _n ...
- Java工具类 Apache Commons:commons-lang
Commons Lang The standard Java libraries fail to provide enough methods for manipulation of its core ...
- 如何设置box shadow的透明度
(从已经死了一次又一次终于挂掉的百度空间人工抢救出来的,发表日期2014-04-24) 今天发现使用box-shadow属性,可以很好的给div添加阴影效果,但是添加的效果如果是: -moz-box- ...
- 闲话Cache:始篇
Caching(缓存)在现代的计算机系统中是一项最古老最基本的技术.它存在于计算机各种硬件和软件系统中,比如各种CPU, 存储系统(IBM ESS, EMC Symmetrix…),数据库,Web服务 ...
- JS瀑布流布局模式(2)
这个例子与上一篇类似,唯一的区别是排序的方式有差别.上一篇是在高度最小的列里插入内容,这个案例是按顺序放置内容. 两种方法各有优缺点.第一种需要在图片内容加载完成的情况下有效,各个列的图高度差异不大. ...
- 用javascript实现简体和繁体字间的转换
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...