第三节:框架前期准备篇之利用Newtonsoft.Json改造MVC默认的JsonResult

一. 背景

  在MVC框架中,我们可能经常会用到 return Json(),而Json方法内部又是一个JsonResult类,那么JsonResult内部又是什么原理呢?在MVC框架中,各种xxxResult便捷了我们的开发,但这些都不是本节的重点,在这里我们只需要知道JsonResult内部的原理即可。

  JsonResult内部原理是基于 JavaScriptSerializer来做的序列化,在使用过程中,有这么几个弊端:

  ①:DateTime类型返回给前端格式不友好:\/Date(1535009968228)\/ ,相当别扭。(PS:前端有很多办法处理的)

  ②:对于前端而言,对于属性名可能更倾向于小写开头,但在C#中,很多都是大写,但JsonResult将原结果默认返回给前端,前端人员可能会有点小不爽。(PS:这也可以算作是一个习惯问题,没有明确的对错)

  ③:循环引用的问题。

  关于使用Newtonsoft.Json改造MVC默认的JsonResult,有很多种方式,本节仅是整理了一下在我日常开发中的使用方法。(PS:这里的MVC版本为: 5.2.4.0)

   这里简单的分析一下JsonResult的源码:

 ①:继承了ActionResult, 实现了ExecuteResult方法。

 ②:解读源码可知,JsonResult内部实现原理是调用了JavaScriptSerializer对象中的Serialize方法,将Json对象转换成了Json字符串,通过:response.Write(javaScriptSerializer.Serialize(this.Data)); 传递给前台。

 ③:默认是禁止Get请求访问的. JsonRequestBehavior.DenyGet。

 ④:在MVC的Action中,return Json(),这里的Json通过源码可知,即new了一个JsonResult对象而已,并且MVC中封装了很多重载。

 

  本节涉及到的知识点有:

    1. MVC中的各种Result,可参考:http://www.cnblogs.com/yaopengfei/p/7910767.html

    2. MVC中的过滤器,可参考:https://www.cnblogs.com/yaopengfei/p/7910763.html

二. 测试JsonResult的弊端

   这里主要测试一下DateTime类型“乱码”(时间戳)问题和默认大小写问题。

后台代码:

复制代码

 1     public ActionResult Json1()2     {3        var msg = new4        {5           ID = 1,6           Name = "ypf1",7           time = DateTime.Now8        };9        return Json(msg);
10    }

复制代码

前台代码:

1   $("#btn1").on("click", function () {
2        $.post("Json1", {}, function (data) {
3              console.log(data);
4        });
5    });

测试结果:

 

下面提供一种解决时间戳转换的问题,使用该js文件,对Date类型进行扩展,代码如下:

 View Code

在前端这么使用,就可以将时间转换成正常的显示:(详细的见上面的代码)

 

三. 自我改造

   有了前面的JsonResult的代码分析,这里先写一种最简单粗暴的改造方式,当然需要实现安装 Newtonsoft.Json程序集。

改造方案一:

   新建YpfSimpleJsonResult类,继承ActionResult类,利用构造函数传递数据,override ExecuteResult方法,在里面利用Newtonsoft进行改写,代码如下:

复制代码

 1     /// <summary>2     /// 简洁版的改写,只是替换了实现方式3     /// </summary>4     public class YpfSimpleJsonResult : ActionResult5     {6         private object _Data = null;7         public YpfSimpleJsonResult(object data)8         {9             this._Data = data;
10         }
11         public override void ExecuteResult(ControllerContext context)
12         {
13             context.HttpContext.Response.ContentType = "application/json";
14             context.HttpContext.Response.Write(JsonConvert.SerializeObject(this._Data));
15         }
16     }

复制代码

测试接口:

复制代码

 1    public ActionResult Json3()2         {3             var msg = new4             {5                 ID = 1,6                 Name = "ypf1",7                 time = DateTime.Now8             };9             return new YpfSimpleJsonResult(msg);
10         }

复制代码

测试结果:

 

改造方案二:

  有了上面的方案的基础,下面深度改造一下,新建YpfJsonResult类,直接继承高层封装JsonResult类,并配置引用问题、默认小写问题、自定义时间格式,代码如下:

复制代码

 1  public class YpfJsonResult : JsonResult2     {3         public YpfJsonResult()4         {5             Settings = new JsonSerializerSettings6             {7                 //1. 忽略循环引用问题,建议设置为Error,这样的话遇到循环引用的时候报错8                 ReferenceLoopHandling = ReferenceLoopHandling.Ignore,9                 //2. 日期格式化,这里可以将Newtonsoft默认的格式进行修改
10                 DateFormatString = "yyyy-MM-dd HH:mm:ss",
11                 //3. 设置属性为开头字母小写的驼峰命名
12                 ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
13             };
14         }
15 
16         public JsonSerializerSettings Settings { get; private set; }
17 
18         public override void ExecuteResult(ControllerContext context)
19         {
20             if (context == null)
21             {
22                 throw new ArgumentNullException("context");
23             }
24             if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
25             {
26                 throw new InvalidOperationException("GET is not allowed");
27             }
28             HttpResponseBase response = context.HttpContext.Response;
29             response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType;
30             if (this.ContentEncoding != null)
31             {
32                 response.ContentEncoding = this.ContentEncoding;
33             }
34             if (this.Data == null)
35             {
36                 return;
37             }
38             var scriptSerializer = JsonSerializer.Create(this.Settings);
39             scriptSerializer.Serialize(response.Output, this.Data);
40         }
41     }

复制代码

测试接口:

复制代码

 1    public ActionResult Json2()2    {3       var msg = new4        {5           ID = 1,6           Name = "ypf1",7           time = DateTime.Now8        };9       //注意:这里的Data是JsonResult类中的一个获取和设置数据的属性。
10       return new YpfJsonResult() { Data = msg };
11    }

复制代码

测试结果:

总结:

   虽然我们通过第二套方案已经达到了我们的目的,但它存在一个弊端,就是侵入性太强,每个方法中都要改写,那么有没有一种方式可以全局控制呢?

  显然是有的,可以考虑使用全局过滤器。

 

四. 全局处理

   这里换一种思路,通过注册一个全局过滤器,对每个Action进行监测,如果使用的是JsonResult,就把JsonResult替换成自己编写的YpfJsonResult,这样的话业务中的调用代码,不需要发生任何变化,仍然可以使用 return Json()方法。

  特别注意:这里的过滤器要使用行为过滤器,并且要在OnActionExecuted方法中进行业务的编写。(这是过滤器执行顺序决定的)

代码分享:

 过滤器代码

编写完过滤器后,需要全局注册一下:

  可以在在FilterConfig文件中注册 filters.Add(new YpfJsonFilter());

  或者直接去:Global文件中:GlobalFilters.Filters.Add(new YpfJsonFilter()); 代码来注册,道理都一样

接口代码,不需要做任何改变,继续沿用return Json()即可。

测试结果:

 

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/438982.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php 跳转qq群代码_邪少xml论坛qqxml代码—QQ音乐可播放框架QQ群任意跳转个人网站链接引流...

邪少XML论坛xml代码—QQ音乐可播放框架效果图&#xff1a;代码如下&#xff1a;<?xml version1.0 encodingUTF-8 standaloneyes ?><msg serviceID"2" templateID"1" action"web" brief"[分享] 古分一道桥" sourceMsgId&quo…

第四节:框架前期准备篇之进程外Session的两种配置方式

一. 基本介绍 1. 背景&#xff1a;Asp.Net默认的Session机制是进程内&#xff0c;存储在服务器端内存中&#xff0c;有这么几个缺点&#xff1a; ①&#xff1a;既然存在内存中&#xff0c;空间有限&#xff0c;不能存储大数据量信息&#xff0c;数据量多的话Session会被挤爆。…

广播延时大约多久_在长沙广播电台打广告要多少钱?

在长沙这个堵城&#xff0c;特别是每天上下班高峰期&#xff0c;很多人都堵在车里。有调查统计显示&#xff0c;长沙市高峰拥堵延时指数1.711&#xff0c;即高峰出行时间是畅通状态下的1.711倍&#xff0c;高峰平均行车速度24.9km/h。在堵车的时候&#xff0c;容易着急上火&…

云计算-Linux-用户管理,用户信息文件详解

云计算-Linux-用户管理,用户信息文件详解 这个就不讲啥了,用户干啥用的还能不知道吗 这个用户目录是在这/etc/skel下的 创建用户 useradd(只有root才能用) 扩展参数 -u指定用户的UID -d指定用户的家目录 -c指定用户的描述信息(备注) -g指定用户基本组 -G指定用户附加组 -s…

第五节:框架前期准备篇之锁机制处理并发

一. 简介 (一). 在处理并发的这个问题上&#xff0c;锁大致分为两类&#xff1a;悲观锁和乐观锁。 1. 悲观锁&#xff1a;悲观的认为每次去拿数据的时候都会被别人修改&#xff0c;所以每次在拿数据的时候都会“上锁”&#xff0c;操作完成之后再“解锁”。 在数据加锁期间&a…

表面粗糙度的基本评定参数是_表面粗糙度100问,讲得明明白白

提醒&#xff1a;点上方↑↑↑“制造原理”订阅后 满足你的好奇来源&#xff1a;机械工程师1&#xff0e; 什么称为表面粗糙度&#xff1f;答&#xff1a;表面粗糙度是指零件加工表面上具有的由较小间距和峰谷所组成的微观几何形状特征。它是一种微观几何形状误差。2&#xff0…

第六节:框架搭建之EF的Fluent Api模式的使用流程

一. 前言 沉寂了约一个月的时间&#xff0c;今天用一篇简单的文章重新回归博客&#xff0c;主要来探讨一下Fluent Api模式在实际项目中的使用流程。 1. Fluent API属于EF CodeFirst模式的一种&#xff0c;EF还有一种模式是DataAnnotations&#xff0c;两种模式各有千秋吧&…

高通modem启动过程_苹果首次承认正自研基带芯片,高通要被抛弃了?

以苹果技术实力&#xff0c;摆脱依赖&#xff0c;只是时间的问题。”作者 | 肖漫苹果和高通的基带芯片故事续集&#xff0c;又开始上映了。据彭博社 12 月 10 日报道&#xff0c;苹果公司芯片负责人对员工表示&#xff0c;苹果已开始为未来的设备自研蜂窝调制解调器&#xff0c…

第七节:框架搭建之页面静态化的剖析

一. 前言 抛砖引玉&#xff1a; 提到项目性能优化&#xff0c;大部分人第一时间就会想到缓存&#xff0c;针对“读多写少”的数据&#xff0c;可以放到缓存里&#xff0c;设置个过期时间&#xff0c;这样就不用每次都去数据库中查询了&#xff0c; 减轻了数据库的压力&#xff…

第八节:数据库层次的锁机制详解和事务隔离级别

一. 基本概念 1.共享锁&#xff1a;(holdlock) (1). select的时候会自动加上共享锁&#xff0c;该条语句执行完&#xff0c;共享锁立即释放&#xff0c;与事务是否提交没有关系。 (2). 显式通过添加(holdlock)来显式添加共享锁&#xff08;比如给select语句显式添加共享锁&…

第九节:基于MVC5+AutoFac+EF+Log4Net的基础结构搭建

一. 前言 从本节开始&#xff0c;将陆续的介绍几种框架搭建组合形式&#xff0c;分析每种搭建形式的优势和弊端&#xff0c;剖析搭建过程中涉及到的一些思想和技巧。 (一). 技术选型 1. DotNet框架&#xff1a;4.6 2. 数据库访问&#xff1a;EF 6.2 (CodeFrist模式) 3. IOC框架…

第十节:基于MVC5+Unity+EF+Log4Net的基础结构搭建

一. 前言 从本节开始&#xff0c;将陆续的介绍几种框架搭建组合形式&#xff0c;分析每种搭建形式的优势和弊端&#xff0c;剖析搭建过程中涉及到的一些思想和技巧。 (一). 技术选型 1. DotNet框架&#xff1a;4.6 2. 数据库访问&#xff1a;EF 6.2 (CodeFrist模式) 3. IOC框架…

a*算法的优缺点_K-近邻算法以及案例

什么是K-近邻算法(KNN)根据邻居判断类型。如果一个样本在特征空间中有K个最相似&#xff08;距离相近&#xff09;的样本大多数属于一个类别&#xff0c;则该样品也属于这个类别。如何求距离呢?非常简单,如图。a1,a2,a3代表样本a的特征值 b1,b2,b3代表b的样本值&#xff0c;根…

android 预约挂号代码_告别排队!用Python定时自动挂号和快捷查询化验报告

作者 | 阿文来源 | 程序人生(ID: coder_life)我什么要做这个事情去年单位体检查出问题来&#xff0c;经过穿刺手术确诊是个慢性肾脏病2期&#xff0c; IGA 肾病三期&#xff0c;可能大家对于这个病并不是很了解&#xff0c;但是另外一个词可能大家都听过&#xff0c;叫"尿…

灵动思绪EF(Entity FrameWork)

很久之前就想写这篇文章了&#xff0c;但是由于种种原因&#xff0c;没有将自己学习的EF知识整理成一片文章。今天我就用CodeFirst和ModelFirst两种方式的简单案例将自己学习的EF知识做个总结。 在讲解EF之前&#xff0c;我们先来看下ORM ORM全称&#xff1a;(Object-Relatio…

json qbytearray 串 转_JSON数据采集网关,json转Modbus RTU串IO口RS485转4~20mA边缘计算智能终端...

JSON数据采集网关边缘计算智能终端是一种能够将各种传感器仪表仪器设备的数据采集后按照JSON格式上传服务器的网关&#xff0c;可以实现云边协同。JSON(JavaScript Object Notation)是java中的数据格式。例如{“Energy”:”100”, “time”:”22:22:15”}这样的格式&#xff0c…

ABP入门系列(3)——领域层定义仓储并实现

一、先来介绍下仓储 仓储&#xff08;Repository&#xff09;&#xff1a; 仓储用来操作数据库进行数据存取。仓储接口在领域层定义&#xff0c;而仓储的实现类应该写在基础设施层。 在ABP中&#xff0c;仓储类要实现IRepository接口&#xff0c;接口定义了常用的增删改查以及…

XCIE-HUAWEI-PBR-MQC-引入形成的路由环路

XCIE-HUAWEI-PBR-MQC-引入形成的路由环路 首先来个测试 给你们选&#xff0c;答案选啥呢? 正确答案在结尾公布 正确答案是C 为什么呢&#xff1f; 首先&#xff0c;虽然ACL有一个齐总是拒绝的&#xff0c;但是呢&#xff0c;他两都是同一条路由 但是呢&#xff01;&#x…

ABP入门系列(5)——展现层实现增删改查

ABP入门系列目录——学习Abp框架之实操演练源码路径&#xff1a;Github-LearningMpaAbp 这一章节将通过完善Controller、View、ViewModel&#xff0c;来实现展现层的增删改查。最终实现效果如下图&#xff1a; 展现层最终效果 一、定义Controller ABP对ASP.NET MVC Controlle…