ASP.NET Core MVC中的IActionFilter.OnActionExecuted方法执行时,Controller中Action返回的对象是否已经输出到Http Response中
我们在ASP.NET Core MVC项目中有如下HomeController:
using Microsoft.AspNetCore.Mvc; namespace AspNetCoreActionFilter.Controllers { public class HomeController : Controller { /// <summary> /// 显示一个网页供测试 /// </summary> public IActionResult Index() { return View(); } /// <summary> /// 返回一个Json对象到客户端浏览器 /// </summary> /// <returns>Json对象</returns> public IActionResult GetJson() { return Json(new { Message = "This is a GetJson message!" }); } } }
其代码非常简单,HomeController只有两个Action:
- Index这个Action,输出一个简单的网页供测试
- GetJson这个Action,输出一个Json对象到客户端浏览器
现在我们在浏览器上输入Url地址"Home/GetJson"来访问HomeController的GetJson这个Action,结果如下:
通过IE浏览器的开发者工具,我们看到,浏览器成功接收到了HomeController的GetJson这个Action返回的Json对象,其message属性值为我们在GetJson这个Action中返回的"This is a GetJson message!"。
然后我们定义一个IActionFilter拦截器叫MyActionFilterAttribute,利用IActionFilter的OnActionExecuted方法,我们可以在HomeController的GetJson这个Action方法执行后,替换GetJson方法返回的Json对象:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using System; namespace AspNetCoreActionFilter.Filters { /// <summary> /// 定义一个IActionFilter拦截器叫MyActionFilterAttribute /// </summary> public class MyActionFilterAttribute : Attribute, IActionFilter { /// <summary> /// IActionFilter.OnActionExecuted在Controller的Action方法执行完后执行 /// </summary> public void OnActionExecuted(ActionExecutedContext context) { //等Controller的Action方法执行完后,通过更改ActionExecutedContext类的Result属性,来替换Action方法返回的Json对象 context.Result = new JsonResult(new { Message = "This is a MyActionFilter message!" }); } /// <summary> /// IActionFilter.OnActionExecuting在Controller的Action方法执行前,但是Action方法的参数模型绑定完成后执行 /// </summary> public void OnActionExecuting(ActionExecutingContext context) { //Do something... //context.Result = new EmptyResult();//在IActionFilter.OnActionExecuting方法中,context的Result属性只要被赋值了不为null,就不会执行Controller的Action了,也不会执行该IActionFilter拦截器的OnActionExecuted方法,同时在该IActionFilter拦截器之后注册的其它Filter拦截器也都不会被执行了 } } }
但问题是当ASP.NET Core MVC执行IActionFilter的OnActionExecuted方法时,HomeController的GetJson这个Action方法返回的Json对象,是否已经被输出到Http Response中发送给客户端浏览器了呢?
我们将上面定义的IActionFilter拦截器MyActionFilterAttribute注册到HomeController的GetJson方法上:
using AspNetCoreActionFilter.Filters; using Microsoft.AspNetCore.Mvc; namespace AspNetCoreActionFilter.Controllers { public class HomeController : Controller { /// <summary> /// 显示一个网页供测试 /// </summary> public IActionResult Index() { return View(); } /// <summary> /// 返回一个Json对象到客户端浏览器 /// </summary> /// <returns>Json对象</returns> [MyActionFilter] public IActionResult GetJson() { return Json(new { Message = "This is a GetJson message!" }); } } }
然后再在浏览器中输入Url地址"Home/GetJson"来访问HomeController的GetJson这个Action,这次结果如下:
我们可以看到这次浏览器收到的Json对象是MyActionFilterAttribute拦截器中OnActionExecuted方法替换的Json对象,其message属性值为"This is a MyActionFilter message!",而HomeController的GetJson这个Action返回的Json对象根本就没有被浏览器收到,说明HomeController的GetJson这个Action返回的Json对象完全没有被输出到Http Response中发送给客户端浏览器。所以这很好地说明了ASP.NET Core MVC中IActionFilter拦截器的OnActionExecuted方法,会在Controller的Action返回的对象被输出到Http Response之前执行。
我们还可以在ASP.NET Core MVC中的.cshtml视图文件中写几个C#代码打上断点,在IActionFilter拦截器的OnActionExecuted方法中也打上断点,在Visual Studio调试中我们会发现,IActionFilter拦截器的OnActionExecuted方法的断点先被执行,然后才执行.cshtml视图文件中的断点,这也很清晰地证明了上面黑色粗体字的观点。当然如果你在Controller的Action方法中,直接使用Response.Body的Stream流输出数据到客户端浏览器,IActionFilter拦截器的OnActionExecuted方法执行时数据肯定已经发送给客户端浏览器了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架