我从一无所知中来,向着无限未知中去

MVC项目中DateTime字段Json格式化输出的几种解决方案

  现在很多的项目都在使用MVC-EF,前段使用vue angularjs 等框架,在使用的过程中,大家可能都出现过一个问题,就是后端返回的JSON数据,关于DateTime字段JSON成了"/Date(20130450000365)"这种形式,这样对于页面呈现使用带来了很大的麻烦,聪明点的同学可能会拿去拆分字符串,取出中间的时间戳进行转换,然后又实用js进行格式化.....

  从上面的步骤来看,这个过程并不简单,甚至繁琐。依我个人的说法就是:是不好用,麻烦,不能普罗大众。哪有没有好的办法呢?下面我就为大家介绍下其他办法

  1.自己封装一个方法,自己设置其中的时间转换规则,下面是代码

public static class JsonHelper
    {
        private static JsonSerializerSettings _jsonSettings;

        #region init
        static JsonHelper()
        {
            IsoDateTimeConverter datetimeConverter = new IsoDateTimeConverter();
            datetimeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
            _jsonSettings = new JsonSerializerSettings();
            _jsonSettings.MissingMemberHandling = MissingMemberHandling.Ignore;
            _jsonSettings.NullValueHandling = NullValueHandling.Ignore;
            _jsonSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            _jsonSettings.Converters.Add(datetimeConverter);
        } 
        #endregion

        #region 将指定的对象序列化成 JSON 数据。
        /// <summary>
        /// 将指定的对象序列化成 JSON 数据。
        /// </summary>
        /// <param name="obj">要序列化的对象。</param>
        /// <returns></returns>
        public static string ToJson(this object obj)
        {
            try
            {
                if (null == obj)
                    return null;
                return JsonConvert.SerializeObject(obj, Formatting.None, _jsonSettings);
            }
            catch (Exception ex)
            {
                throw new Exception("Json序列化出错:" + ex.Message);
            }
        } 
        #endregion

        #region  将指定的 JSON 数据反序列化成指定对象。
        /// <summary>
        /// 将指定的 JSON 数据反序列化成指定对象。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="json">JSON 数据。</param>
        /// <returns></returns>
        public static T FromJson<T>(this string json)
        {
            try
            {
                return JsonConvert.DeserializeObject<T>(json, _jsonSettings);
            }
            catch (Exception ex)
            {
                throw new Exception("Json反序列化出错:" + ex.Message);
            }
        } 
        #endregion
    }
View Code

  这是封装的一个扩展方法,使用比较简单,但是不够灵活,比如某些时间我们需要显示年月日时分秒,但有的时候只显示年月日,这就不好控制了。

  使用方法如下:

        public string Get()
        {
            return new { Time = DateTime.Now }.ToJson();
        }

        public ContentResult Get()
        {
            return Content(new { Time = DateTime.Now }.ToJson());
        }
        //这两种方法发生使用的时候存在特殊环境下js识别不了,认为是字符串的问题
View Code

  2.控制器直接返回object的形式

 public object Get()
        {
            return new { Time = DateTime.Now };
        }

  这种方法使用起来比上面更简单,但是问题更大,它不能解析List类型,比如

        //能正常解析
        public object Get()
        {
            return new { Childe = new { Time = DateTime.Now } };
        }
        //不能正常解析
        //页面解析结果为:System.Collections.Generic.List`1[System.Object]

        public List<object> GetList()
        {
            return new List<object> { new { time = DateTime.Now } };
        }
View Code

  以上两种方法我个人都不推荐使用!下面推荐第三种方法给大家使用:

  3.定义只读属性的方法,在项目中我们可以这么写:

        public DateTime Time { get; set; }

        /// <summary>
        /// 不会映射到数据库,LastUpdateTime字段显示用
        /// </summary>
        [NotMapped]
        public string ShowTime { get { return Time.ToString("yyyy-MM-dd"); } }

  上面的代码是适用于EF的Model,同时也是适用于任何类对象,结构成语。上面代码中我写的NotMapped只是用于EF Model中,如果你不是EF Model请去掉

  看到这里可能有部分同学会问了,如果使用的是数据库优先怎么处理?答案:使用部分类解决,请看以下代码:

    public partial class ProjectHistory
    {
        /// <summary>
        /// 不会映射到数据库,LastUpdateTime字段显示用
        /// </summary>
        [NotMapped]
        public string ShowTime { get { return Time.ToString("yyyy-MM-dd"); } }
    }

  这种方法可以很好的解决第1个问题中不灵活的问题,如果这个字段有多种显示形式我可以编写多个只读属性解决

  但是呢,这个方案还是存在一个问题,在ORM项目中,很多同学很多时候啊返回的是匿名类型,这时候就尴尬了。匿名类型查询数据库时不能对时间进行ToString()格式化(Linq不支持),必须查询出来再次创建匿名类型才能进行ToSring()格式化,这样看起来就很麻烦,但是输出格式却很灵活,这个可以配合其他方法一起使用,效果更好!

  4.定义全局设置,这一种方法只适用于webapi的项目,在Global.asax中添加以下代码:

            //清除所有的序列化化适配器
            GlobalConfiguration.Configuration.Formatters.Clear();
            //创建一个JSON序列化适配器
            JsonMediaTypeFormatter format = new JsonMediaTypeFormatter();
            //重新定义JSON时间序列化配置器
            format.SerializerSettings.DateFormatString = "yy-MM-dd HH:mm:ss";
            //注册JSON序列化适配器
            GlobalConfiguration.Configuration.Formatters.Add(format);

  这种方法只能正对WebApi 项目中的Api控制器,一样和方法1配置存在不灵活的问题,其实我认为MVC都应该支持这种定义的才对,但是我确实没找到如何定义普通控制器的方法,不知道有没有大神知道的?求回复

 

  以上就是我个人想到的4种方法,当然只是针对后端输出的方法,前端的朋友怎么处理,方法应该有很多种吧!大家谁便百度一下一大堆啦!

  最后感谢大家阅读我的博客,才刚开始写博客,可能内容有点啰嗦,文笔有点不好,错别字还有点多!请大家多多理解包含,也希望大家多多发言,有什么意见尽管提!谢谢大家阅读!

  

posted @ 2017-09-22 09:12  何苦来哉  阅读(679)  评论(0编辑  收藏  举报

知识才让我觉得世界如此美好