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 对象中 ...
随机推荐
- DaoFactory.java
package com; import com.isoftstone.fwk.dao.ActionDao; import com.isoftstone.fwk.dao.Dao; import com. ...
- mysql编码详解
在开发程序的时候,我们使用mysql数据库开发的时候,有时会碰到自己明明输入的是中文,为什么数据库中存储的就是???? 1.在配置Connection URL时,加上?useUnicode=true& ...
- Linux top和负载的解释
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.下面详细介绍它的使用方法. top - 01:06:48 up 1:22, ...
- HDU 5534 Partial Tree (完全背包变形)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5534 题意: 给你度为1 ~ n - 1节点的权值,让你构造一棵树,使其权值和最大. 思路: 一棵树上 ...
- POJ 3169 Layout (差分约束)
题意:给定一些母牛,要求一个排列,有的母牛距离不能超过w,有的距离不能小于w,问你第一个和第n个最远距离是多少. 析:以前只是听说过个算法,从来没用过,差分约束. 对于第 i 个母牛和第 i+1 个, ...
- Top 7 Myths about HTTPS
Myth #7 – HTTPS Never Caches People often claim that HTTPS content is never cached by the browser; p ...
- How Tomcat Works(十二)
tomcat容器通过一个称为Session管理器的组件来管理建立的Session对象,该组件由org.apache.catalina.Manager接口表示:Session管理器必须与一个Contex ...
- kindeditor 上传图片 显示绝对 路径
在前台页面上 效果图 另外附上 urlType 属性的 参数说明: 改变站内本地URL,可设置空.relative.absolute.domain. 空为不修改URL,relative为相对路径,ab ...
- ASP.NET MVC 修改视图的默认路径(MVC2,MVC3)
ASP.NET MVC2 修改视图的默认路径 步骤:1.编写继承自WebFormViewEngine的类,重写视图路径 2.在Application_Start()中添加语句: ViewEngines ...
- Flex编程注意之直接获取某个组件的对象(this[]用法)通过id获取控件
有这样一个需求:假如你new了一百次Button,同时这些button的id分别赋值如btn1.id = "button1"; btn2.id = "button2&qu ...