欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

解决ASP.NET MVC返回的JsonResult 中 日期类型数据格式问题,和返回的属性名称转为“驼峰命名法”和循环引用问题

程序员文章站 2022-05-28 23:06:59
DateTime类型数据格式问题 问题 在使用ASP.NET MVC 在写项目的时候发现,返回给前端的JSON数据,日期类型是 Date(121454578784541) 的格式,需要前端来转换一下才能用来使用。 C#对象属性名称转换成JSON自动转成“驼峰命名法” 问题 在C#中推荐的属性命名方式 ......

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"}