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 对象中 ...
随机推荐
- spring+jpg环境下,spring实现文件上传
jsp: <form method="post" action="excel.do?method=inputExcel" enctype="mu ...
- Eclipse设置、调优、使用
eclipse调优 一般在不对eclipse进行相关设置的时候,使用eclipse总是会觉得启动好慢,用起来好卡,其实只要对eclipse的相关参数进行一些配置,就会有很大的改善. 加快启动速度 1. ...
- 特现C语言编程特点的小代码,itoa,数值转换成字符串
#define BASE_MAX (26 + 10) char const* itostr(int x, int base) { /* map 居中, 支技负余数 */ static char con ...
- Tair分布式key/value存储
[http://www.lvtao.net/database/tair.html](特别详细) tair 是淘宝自己开发的一个分布式 key/value 存储引擎. tair 分为持久化和非持久化 ...
- C++学习笔记之运算符重载
一.运算符重载基本知识 在前面的一篇博文 C++学习笔记之模板(1)——从函数重载到函数模板 中,介绍了函数重载的概念,定义及用法,函数重载(也被称之为函数多态)就是使用户能够定义多个名称相同但特征标 ...
- Nazo解密游戏攻略
啊,终于腾出时间来玩这个游戏了,顺手写一下攻略吧…… 第0关:http://cafebabe.cc/nazo/ 第一关:第一关很简单 点一下就好了 http://cafebabe.cc/nazo/le ...
- WinForm特效:拦截窗体上各个部位的点击
windows窗体的标题栏无法直接通过一些默认的事件来控制,需要了解和WM_NCHITTEST相关的windows消息. 以下示例演示了最简单的效果片断: 他会把客户区和标题栏的效果互换,比如无法按住 ...
- ExtJS grid tableGrid study
Q: How to color the text in the grid Try: http://dev.sencha.com/playpen/docs/output/Ext.grid.TableG ...
- corner2
Original: https://github.com/LondonX/corner2 Backup: https://github.com/eltld/corner2
- iOS开发——UI篇Swift篇&UIToolbar
UIToolbar class UIToolBarUISearchBar: UIViewController,UISearchBarDelegate { var titleString:String! ...