摘要: 对最近mvc项目研发过程中碰到的以及解决方法的一些总结.从脚本/样式/api help文档/部署方面碰到的相关问题.如:RemoteAttribute在IE下缓存? web api 调用数据唯一的数组参数等.希望对你有点帮助 阅读全文
posted @ 2015-11-09 20:33 卤鸽 阅读(1029) 评论(4) 推荐(1) 编辑
摘要: 使用EnyimMemcached客户端进行通信使用Memcached,以减轻数据库负载. 使用MemcachedProviders解决Session的同步. 阅读全文
posted @ 2015-09-13 10:54 卤鸽 阅读(2233) 评论(1) 推荐(4) 编辑
摘要: 本文通过一个请求窥探AspNet的生命周期,也从WebForm与Mvc两种进行展示其主要响应请求的过程,主要通过图表形式展示出来。 阅读全文
posted @ 2015-08-22 12:39 卤鸽 阅读(1471) 评论(2) 推荐(4) 编辑
摘要: AspNet MVC中比较重要的上下文,有如下: 核心的上下文有HttpContext(请求上下文),ControllerContext(控制器上下文) 过滤器有关有五个的上下文ActionExecutingContext,ActionExecutedContext,ResultExecutingContext,ResultExecutedContext,ExceptionContext 视图相关的上下文ViewContext 阅读全文
posted @ 2015-02-20 11:03 卤鸽 阅读(2466) 评论(3) 推荐(9) 编辑

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; }
    }
}
View Code

  笔者这里先贴出序列化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[0].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

posted @ 2015-06-22 11:42 卤鸽 阅读(5860) 评论(9) 推荐(4) 编辑
摘要: 1、使用Nhibernate进行增删查改,并且映射一对多,多对多的关系 2、封装公用接口IRepository,并且实现该接口抽象类(提供本文范例源码下载) 阅读全文
posted @ 2015-06-08 06:28 卤鸽 阅读(2627) 评论(3) 推荐(6) 编辑
摘要: 串口SerialPort类使用Write之后进行Read之后可能存在数据延后发送或者数据合并发送,笔者使用线程等待锁定串口的工作状态的形式进行获取准确的数据。这样能够一定的解决数据失真的情况,但是高密集的命令下可以通过事件订阅的方式得到合理的解决 阅读全文
posted @ 2015-05-08 19:49 卤鸽 阅读(2577) 评论(0) 推荐(0) 编辑
摘要: OxyPlot的基础使用(自定义曲线、自定义坐标轴以及实时生成图表),提供源码下载 阅读全文
posted @ 2015-05-07 21:58 卤鸽 阅读(24582) 评论(13) 推荐(10) 编辑
摘要: ASP .NET SignalR[1] 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信。什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知消息及调用方法,当然这是实时操作的。 阅读全文
posted @ 2014-08-30 20:47 卤鸽 阅读(2073) 评论(0) 推荐(2) 编辑
摘要: Asp.Net缓存包括服务器端缓存(含:请求域缓存、用户域内缓存、应用程序域内缓存、Asp.Net缓存、输出缓存、甜圈圈缓存、甜圈圈洞缓存)和客户端缓存(含:浏览器缓存和AppCache缓存和本地缓存) 阅读全文
posted @ 2014-04-22 22:01 卤鸽 阅读(1120) 评论(3) 推荐(1) 编辑
点击右上角即可分享
微信分享提示