解决ASP.NET MVC返回的JsonResult 中 日期类型数据格式问题,和返回的属性名称转为“驼峰命名法”和循环引用问题
程序员文章站
2023-03-26 15:30:33
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"}