0  缘由

  笔者最近在web api端使用Json.Net进行序列化处理,而在调用端使用DataContractSerializer进行反序列化,遇到日期时间处理反序列化不成功【备注:笔者使用Net Framework 4.0】。究其原因,Json.Net默认的日期输出是ISO标准时间,而微软默认的输出与解析日期格式是/Date(1242357713797+0800)/。可以看出我们只需将ISO的标准时间转换成微软能够识别日期时间格式即可。最后笔者就想重新对比下Net中Json序列化和反序列化的三种处理方式,以及性能。

1  介绍

Net中Json序列化反序列化一般常用的有三种:

  • JavaScriptSerializer[位于程序集:System.Web.Extension.dll,命令空间:System.Web.Script.Serialization]
  • DataContractSerializer[位于程序集:System.Runtime.Serialization.dll,命名空间:System.Runtime.Serialization.Json]
  • JsonConvert[位于程序集:Newtonsoft.Json.dll,命名空间:Newtonsoft.Json],外部引用库,可通过Nuget进行获取Json.Net

  笔者将分别对这三种进行序列化与反序列化复杂对象,使用Stopwatch进行监测其运行的时间。对比Stopwatch的运行时间,从而得出性能较佳的序列化Json的实现

2  三者对比

  新建一个Mvc3.0 项目命名为JsonConvertSample,使用Nuget引入Json.Net(在程序包管理器控制台键入:Install-Package Newtonsoft.Json),准备一个复杂类User,以及对比类JsonCompare。主要代码如下:

//=====================================================
//Copyright (C) www.cnblogs.com/luge
//All rights reserved
//文件名: JsonCompare
//创建时间: 2015-06-21
//当前登录用户名: 卤鸽
//描述:
//====================================================== namespace JsonConvertSample.Models
{
public class JsonCompare
{
public double DataContractSerializeTime { get; set; } public string DcsString { get; set; } public double JavascriptSerializeTime { get; set; } public string jsString { get; set; } public double JsonNetTime { get; set; } public string jnString { get; set; } public int Capacity { get; set; }
} } namespace JsonConvertSample.Models
{
public class User
{ public int UserID { get; set; } public string UserName { get; set; } public decimal Saraly { get; set; } public Address Location { get; set; } public List<School> Schools { get; set; } public DateTime BirthDate { get; set; }
} public class Address
{
public string Province { get; set; } public string City { get; set; }
} public class School
{
public string SchoolName { get; set; } public string SchoolDesc { get; set; }
}
}

  笔者这里先贴出序列化Json三种不同的泛型实现(详细可下载源码查看)

#region DataContractJsonSerializer

        /// <summary>
/// 序列化json字符串
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <param name="datetimePattern"> 替换Json的Date字符串 </param>
/// <returns></returns>
public static string SerializeByContract<T>(T obj, string datetimePattern = null)
where T : class
{
string jsonString = string.Empty; if (obj == null)
return jsonString; var ser = new DataContractJsonSerializer(typeof(T));
using (var ms = new MemoryStream())
{
ser.WriteObject(ms, obj);
jsonString = Encoding.UTF8.GetString(ms.ToArray());
} if (!string.IsNullOrEmpty(datetimePattern))
{ MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString);
Regex reg = new Regex(datetimePattern);
jsonString = reg.Replace(jsonString, matchEvaluator);
} return jsonString;
} /// <summary>
/// json反序列化成对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="jsonString"></param>
/// <param name="datetimePattern">匹配时间的正则表达式</param>
/// <returns></returns>
public static T DeserializeByContract<T>(string jsonString, string datetimePattern = null)
where T : class
{
if (string.IsNullOrEmpty(jsonString))
{
return default(T);
} if (!string.IsNullOrEmpty(datetimePattern))
{
MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertDateStringToJsonDate);
var reg = new Regex(datetimePattern);
jsonString = reg.Replace(jsonString, matchEvaluator);
} var ser = new DataContractJsonSerializer(typeof(T));
var jsonByteArr = Encoding.UTF8.GetBytes(jsonString);
using (var ms = new MemoryStream(jsonByteArr))
{
object obj = ser.ReadObject(ms);
return obj as T;
} } #endregion #region JavaScriptSerializer public static string SerializeByJavaScript<T>(T obj)
where T : class
{
var jsonString = string.Empty; if (obj == null)
{
return jsonString;
} JavaScriptSerializer js = new JavaScriptSerializer();
//<!--进行序列化或反序列化时出错。字符串的长度超过了为 maxJsonLength 属性设置的值-->
js.MaxJsonLength = int.MaxValue;
jsonString = js.Serialize(obj); return jsonString;
} public static T DeserializeByJavaScript<T>(string jsonString)
where T : class
{
T obj;
if (string.IsNullOrEmpty(jsonString))
{
obj = null;
return obj;
} JavaScriptSerializer js = new JavaScriptSerializer();
js.MaxJsonLength = int.MaxValue;
obj = js.Deserialize<T>(jsonString); return obj;
}
#endregion #region Json.Net public static string SerializeByJsonNet<T>(T obj)
where T : class
{
var jsonString = string.Empty; if (obj == null)
return jsonString; jsonString = JsonConvert.SerializeObject(obj); return jsonString; } public static T DeserializeByJsonNet<T>(string jsonString)
where T : class
{
T obj = null;
if (string.IsNullOrEmpty(jsonString))
{
return obj;
} obj = JsonConvert.DeserializeObject<T>(jsonString);
return obj;
} #endregion

  测试代码局部代码(详细可下载源码查看):

       Stopwatch sw = new Stopwatch();
sw.Start(); jsonCompare.DcsString = JsonFormat.SerializeByContract<IList<User>>(list); sw.Stop();
jsonCompare.DataContractSerializeTime = sw.ElapsedTicks;

  根据不同方式序列化Json得出的结果

  由上面的图片结果可以得出结论:Json.Net 优于 DataContractSerialize, DataContractSerialize 优于 JavaScriptSerialize,而且Json.Net甩JavaScriptSerialize几大街。

4、日期时间的处理

  本文篇头对笔者遇到的问题已经提出处理方案。针对DataContractSerializer进行反序列化日期时间(由json.net序列化)的处理,如果在Net4.0中,正则表达式匹配对日期类型统一替换即可实现之;当然在Net4.5解决方法就更加简单,只需如下设置,即可完成反序列化json。核心处理代码如下:

#if Net45
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T), new DataContractJsonSerializerSettings()
{
DateTimeFormat = new DateTimeFormat("yyyy-MM-dd'T'HH:mm:ss")
});
#endif
#if Net40
private static string ConvertDateStringToJsonDate(Match m)
{
string result = string.Empty;
DateTime dt = DateTime.Parse(m.Groups[].Value);
dt = dt.ToUniversalTime(); TimeSpan ts = dt - DateTime.Parse("1970-01-01");
result = string.Format("\\/Date({0}+0800)\\/",ts.TotalMilliseconds.ToString("f0"));
return result;
}
string datetimePattern="(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)(?:([\+-])(\d{2})\:(\d{2}))?Z?";
MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertDateStringToJsonDate);
var reg = new Regex(datetimePattern);
jsonString = reg.Replace(jsonString, matchEvaluator);
#endif

5、总结与源码

  • JavaScriptSerialize如果序列化对象过大时将会出现“进行序列化或反序列化时出错。字符串的长度超过了为 maxJsonLength 属性设置的值”,只需设置MaxJsonLength=int.MaxValue
  • 源码(如果觉得不错请点赞下,有误的话请指出,卤鸽在此感谢)

参考:

http://blog.csdn.net/cncdns/article/details/6164389

Net中JSON序列化和反序列化处理(日期时间特殊处理)的更多相关文章

  1. 在net中json序列化与反序列化 面向对象六大原则 (第一篇) 一步一步带你了解linq to Object 10分钟浅谈泛型协变与逆变

    在net中json序列化与反序列化   准备好饮料,我们一起来玩玩JSON,什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法 Json语法规则 ...

  2. C#中JSON序列化和反序列化

    有一段时间没有到博客园写技术博客了,不过每天逛逛博客园中大牛的博客还是有的,学无止境…… 最近在写些调用他人接口的程序,用到了大量的JSON.XML序列化和反序列化,今天就来总结下json的序列化和反 ...

  3. 在net中json序列化与反序列化

    准备好饮料,我们一起来玩玩JSON,什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法 Json语法规则: 数据在键值对中 数据由逗号分隔 花括 ...

  4. .Net中json序列化与反序列化

    NuGet中下载Newtonsoft.Json插件. public class JsonHelper<T>{ public static string ModelToJsonString( ...

  5. 转:Json序列化和反序列化

    JSON是专门为浏览器中的网页上运行的JavaScript代码而设计的一种数据格式.在网站应用中使用JSON的场景越来越多,本文介绍 ASP.NET中JSON的序列化和反序列化,主要对JSON的简单介 ...

  6. Scala中使用 Jackson API 进行JSON序列化和反序列化

    1.  什么是 Json 序列化 和 反序列化 序列化 => 将 Java对象 转换成 json字符串反序列化 => 将 json字符串 转换成 Java对象 2. 依赖包 说明 < ...

  7. day5-python中的序列化与反序列化-json&pickle

    一.概述 玩过稍微大型一点的游戏的朋友都知道,很多游戏的存档功能使得我们可以方便地迅速进入上一次退出的状态(包括装备.等级.经验值等在内的一切运行时数据),那么在程序开发中也存在这样的需求:比较简单的 ...

  8. WPF中的常用布局 栈的实现 一个关于素数的神奇性质 C# defualt关键字默认值用法 接口通俗理解 C# Json序列化和反序列化 ASP.NET CORE系列【五】webapi整理以及RESTful风格化

    WPF中的常用布局   一 写在开头1.1 写在开头微软是一家伟大的公司.评价一门技术的好坏得看具体的需求,没有哪门技术是面面俱到地好,应该抛弃对微软和微软的技术的偏见. 1.2 本文内容本文主要内容 ...

  9. 在SpringMVC中,当Json序列化,反序列化失败的时候,会抛出HttpMessageNotReadableException异常, 当Bean validation失败的时候,会抛出MethodArgumentNotValidException异常,因此,只需要在ExceptionHandler类中添加处理对应异常的方法即可。

    在SpringMVC中,当Json序列化,反序列化失败的时候,会抛出HttpMessageNotReadableException异常, 当Bean validation失败的时候,会抛出Method ...

随机推荐

  1. Maven-3.2.2安装配置

    (1)安装JDK,这里是1.7.0_51 (2)Maven-3.2.2下载地址:http://mirrors.cnnic.cn/apache/maven/maven-3/3.2.2/binaries/ ...

  2. machine learning----->谷歌Cloud Machine Learning平台

    1.谷歌Cloud Machine Learning平台简介: 机器学习的三要素是数据源.计算资源和模型.谷歌在这三个方面都有强大的支撑:谷歌不仅有种类丰富且数量庞大的数据资源,而且有强大的计算机群提 ...

  3. 在Windows上运行Tomcat

    一.下载jdk 百度搜索jdk 64位 下载,直接就有链接.或者官网下载 二.下载tomcat http://tomcat.apache.org/ 三.安装jdk并配置环境 安装jdk后进入控制面板- ...

  4. 理解GC日志

    每一种收集器的日志形式都是由它们自身的实现所决定的,换而言之,每个收集器的日志格式都可以不一样.但虚拟机设计者为了方便用户阅读,将各个收集器的日志都维持一定的共性,例如以下两段典型的GC日志: 33. ...

  5. 最近写了一个红包雨的小功能,但感觉自己的js还有很多地方可以提高,望大神们可以帮忙指点一二

    js部分 'use strict'; function RedEnvelope(options){ if(this === window){ return new RedEnvelope(option ...

  6. Visual Studio Professional 2015 key

    Visual Studio Professional 2015 Key : HMGNV-WCYXV-X7G9W-YCX63-B98R2 Visual Studio Enterprise 2015 Ke ...

  7. 【java】:解析xml

    ==========================================xml文件<?xml version="1.0" encoding="GB231 ...

  8. 正向代理与反向代理的区别【Nginx读书笔记】(zz)

    正向代理与反向代理的区别[Nginx读书笔记]       正向代理的概念 正向代理,也就是传说中的代理,他的工作原理就像一个跳板,简单的说,我是一个用户,我访问不了某网站,但是我能访问一个代理服务器 ...

  9. [Chapter 3 Process]Practice 3.9 Describe the actions token by a kernel to content-switch between processes.

    3.9 Describe the actions token by a kernel to content-switch between processes. 答案: 内核在进行进程上下文切换时, 首 ...

  10. P1403约数研究

    洛谷1403 约数研究 题目描述 科学家们在Samuel星球上的探险得到了丰富的能源储备,这使得空间站中大型计算机"Samuel2"的长时间运算成为了可能.由于在去年一年的辛苦工作 ...