datetime类型数据格式问题

问题

在使用asp.net mvc 在写项目的时候发现,返回给前端的json数据,日期类型是 date(121454578784541) 的格式,需要前端来转换一下才能用来使用。

c#对象属性名称转换成json自动转成“驼峰命名法”

问题

在c#中推荐的属性命名方式是“帕斯卡命名法”【首字母大写】但是在前端推荐命名方式为“驼峰命名法”【首字母小写】,这样如果直接序列化c#对象,返回的属性就是大写的了

mvc 默认的返回jsonresult在序列化有循环引用对象时候会出现异常

问题

序列化类型为“xxxxxx.xxxx.xxx”的对象时检测到循环引用。

解决办法

创建新的 jsonresult 对象

使用新的json序列化组件 newtonsoft.json

install-package newtonsoft.json

创建新的 jsonresult 对象
然后在新的 jsonresult 类型中将处理json序列化的对象改为 newtonsoft.json
并设置json转换的日期格式为 yyyy-mm-dd hh:mm:ss 例如:【2020-03-28 17:36:23】
并设置 转换的属性为“驼峰命名法”

/// <summary>
/// json结果返回对象
/// </summary>
public class jsonnetresult : jsonresult
{
    /// <summary>
    /// 实例化json结果返回对象
    /// </summary>
    /// <param name="data">需要序列化的对象</param>
    /// <returns>json结果对象</returns>
    public jsonnetresult(object data)
        : this(data, jsonrequestbehavior.denyget)
    {
    }

    /// <summary>
    /// 实例化json结果返回对象
    /// </summary>
    /// <param name="data">需要序列化的对象</param>
    /// <param name="jsonrequestbehavior">设置是否允许get请求获取json结果对象</param>
    /// <returns>json结果对象</returns>
    public jsonnetresult(object data, jsonrequestbehavior jsonrequestbehavior)
    {
        this.data = data;
        this.jsonrequestbehavior = jsonrequestbehavior;
        this.settings = new jsonserializersettings
        {
            referenceloophandling = referenceloophandling.ignore, //忽略循环引用
            dateformatstring = "yyyy-mm-dd hh:mm:ss", //输出的日期格式
            contractresolver = new camelcasepropertynamescontractresolver() //设置属性的名称为“驼峰命名法”
        };
    }

    /// <summary>
    /// json序列化设置对象
    /// </summary>
    public jsonserializersettings settings { get; set; }

    /// <summary>
    /// 向响应流返回结果方法
    /// </summary>
    public override void executeresult(controllercontext context)
    {
        //判断当前请求是否为get且判断是否允许get获取json,不允许就报错
        if ("get".equals(context.httpcontext.request.httpmethod, stringcomparison.ordinalignorecase) &&
            this.jsonrequestbehavior == jsonrequestbehavior.denyget)
            throw new exception("不允许get请求返回json数据!");

        //判断是否改变响应数据编码
        if (this.contentencoding != null)
            context.httpcontext.response.contentencoding = this.contentencoding;
        //如果当前需要序列化的数据为null就直接返回
        if (this.data == null)
            return;
        //设置响应数据内容格式为 json
        context.httpcontext.response.contenttype =
            string.isnullorempty(this.contenttype) ? "application/json" : this.contenttype;
        //向响应流写入序列化的数据
        jsonserializer.create(settings).serialize(context.httpcontext.response.output, this.data);
    }
}

 

使用新的 jsonresult 对象 方法一(推荐)

使用过滤器,将jsonresult对象替换成 jsonnetresult 对象

创建一个actionfilter,用来将返回的jsonresult对象转换成新的jsonnetresult对象

/// <summary>
/// 将action返回的jsonresult转换成jsonnetaction
/// </summary>
public class jsonnetactionfilter : iactionfilter
{
    public void onactionexecuting(actionexecutingcontext filtercontext)
    {
    }

    public void onactionexecuted(actionexecutedcontext filtercontext)
    {
        //判断是jsonresult对象
        if (filtercontext.result is jsonresult && !(filtercontext.result is jsonnetresult))
        {
            //得到原jsonresult对象
            var jsonresult = (jsonresult) filtercontext.result;
            //创建新的jsonnetresult对象
            var jsonnetresult = new jsonnetresult(jsonresult.data)
            {
                contentencoding = jsonresult.contentencoding,
                contenttype = jsonresult.contenttype,
                jsonrequestbehavior = jsonresult.jsonrequestbehavior,
                maxjsonlength = jsonresult.maxjsonlength,
                recursionlimit = jsonresult.recursionlimit
            };
            //将新的jsonnetresult对象赋值给返回结果
            filtercontext.result = jsonnetresult;
        }
    }
}

在global.asax注册过滤器

public class mvcapplication : httpapplication
{
    protected void application_start()
    {
        arearegistration.registerallareas();
        routeconfig.registerroutes(routetable.routes);

        //注册过滤器
        globalfilters.filters.add(new jsonnetactionfilter());
    }
}

使用

public class homecontroller : controller
{
    public actionresult getstudent()
    {
        var student = new studentdto
        {
            id = 1,
            name = "张三",
            age = 18,
            classname = "b36",
            createdate = datetime.now,
        };
        return json(student);
    }
}

返回给前端的json数据

{"id":1,"name":"张三","age":18,"classname":"b36","createdate":"2020-03-28 17:47:29"}

使用新的 jsonresult 对象 方法二

创建一个basecontroller 来重写他的json()方法

创建一个 basecontroller 类 继承自 controller 类
并重写他的 json() 方法,其他controller 类都继承自 basecontroller
这样 可以直接沿用之前的 返回json对象方法

/// <summary>
/// 父 控制器
/// </summary>
public class basecontroller : controller
{
    /// <summary>
    /// 返回 jsonnetresult 对象
    /// </summary>
    /// <param name="data">需要返回序列化的对象</param>
    /// <param name="contenttype">内容格式</param>
    /// <param name="contentencoding">内容编码</param>
    /// <param name="behavior">指定是否允许来自客户端的 http get 请求。</param>
    /// <returns>jsonresult对象</returns>
    protected override jsonresult json(object data, string contenttype, encoding contentencoding, jsonrequestbehavior behavior)
    {
        return new jsonnetresult(data)
        {
            contenttype = contenttype,
            contentencoding = contentencoding,
            jsonrequestbehavior = behavior
        };
    }
}

使用

public class homecontroller : basecontroller
{
    public actionresult getstudent()
    {
        var student = new studentdto
        {
            id = 1,
            name = "张三",
            age = 18,
            classname = "b36",
            createdate = datetime.now,
        };
        //将当前对象序列化成json返回给前端
        return json(student);
    }
}

返回给前端的json数据

{"id":1,"name":"张三","age":18,"classname":"b36","createdate":"2020-03-28 17:47:29"}

使用新的 jsonresult 对象 方法三

创建一个json帮助类

/// <summary>
/// json帮助类
/// </summary>
public static class jsonhelper
{
    /// <summary>
    /// 将一个对象序列化成json格式字符串返回给请求方
    /// </summary>
    /// <param name="obj">需要序列化的对象</param>
    /// <param name="jsonrequestbehavior">设置是否允许get请求获取json结果对象</param>
    /// <returns>json结果对象</returns>
    public static jsonnetresult json(object obj,
        jsonrequestbehavior jsonrequestbehavior = jsonrequestbehavior.denyget)
    {
        return new jsonnetresult(obj, jsonrequestbehavior);
    }

    /// <summary>
    /// 将当前对象序列化成json格式字符串返回给请求方
    /// </summary>
    /// <param name="obj">需要序列化的对象</param>
    /// <param name="jsonrequestbehavior">设置是否允许get请求获取json结果对象</param>
    /// <returns>json结果对象</returns>
    public static jsonnetresult tojsonresult(this object obj,
        jsonrequestbehavior jsonrequestbehavior = jsonrequestbehavior.denyget)
    {
        return new jsonnetresult(obj, jsonrequestbehavior);
    }
}

使用

public actionresult getstudent()
{
    var student = new studentdto
    {
        name = "张三",
        age = 18,
        classname = "b36",
        createdate = datetime.now,
    };
    //直接调用扩展方法 tojsonresult 来获取新的 jsonresult
    return student.tojsonresult();
}

返回给前端的json数据

{"id":1,"name":"张三","age":18,"classname":"b36","createdate":"2020-03-28 17:47:29"}