在ASP.NET Core MVC中子类Controller拦截器要先于父类Controller拦截器执行
我们知道在ASP.NET Core MVC中Controller上的Filter拦截器是有执行顺序的,那么如果我们在有继承关系的两个Controller类上,声明同一种类型的Filter拦截器,那么是父Controller类的Filter拦截器先执行呢,还是子Controller类的Filter拦截器先执行呢?
首先我们新建一个ASP.NET Core MVC项目。
然后我们新建四个IActionFilter拦截器:MyActionOneAttribute、MyActionTwoAttribute、MyActionThreeAttribute和MyActionFourAttribute
MyActionOneAttribute拦截器将会全局声明在ASP.NET Core MVC项目的所有Controller上:
/// <summary> /// MyActionOneAttribute拦截器将会全局声明在ASP.NET Core MVC项目的所有Controller上 /// </summary> public class MyActionOneAttribute : Attribute, IActionFilter { public void OnActionExecuted(ActionExecutedContext context) { using (var writer = new StreamWriter(context.HttpContext.Response.Body)) { writer.Write("<div>MyAction 1 OnActionExecuted</div></body></html>"); } } public void OnActionExecuting(ActionExecutingContext context) { using (var writer = new StreamWriter(context.HttpContext.Response.Body)) { context.HttpContext.Response.ContentType = "text/html"; context.HttpContext.Response.StatusCode = 200; writer.Write("<html><head></head><body><div>MyAction 1 OnActionExecuting</div>"); } } }
MyActionTwoAttribute拦截器将会声明在父Controller类BaseController上:
/// <summary> /// MyActionTwoAttribute拦截器将会声明在父Controller类BaseController上 /// </summary> public class MyActionTwoAttribute : Attribute, IActionFilter { public void OnActionExecuted(ActionExecutedContext context) { using (var writer = new StreamWriter(context.HttpContext.Response.Body)) { writer.Write("<div>MyAction 2 OnActionExecuted</div>"); } } public void OnActionExecuting(ActionExecutingContext context) { using (var writer = new StreamWriter(context.HttpContext.Response.Body)) { writer.Write("<div>MyAction 2 OnActionExecuting</div>"); } } }
MyActionThreeAttribute拦截器将会声明在子Controller类HomeController上:
/// <summary> /// MyActionThreeAttribute拦截器将会声明在子Controller类HomeController上 /// </summary> public class MyActionThreeAttribute : Attribute, IActionFilter { public void OnActionExecuted(ActionExecutedContext context) { using (var writer = new StreamWriter(context.HttpContext.Response.Body)) { writer.Write("<div>MyAction 3 OnActionExecuted</div>"); } } public void OnActionExecuting(ActionExecutingContext context) { using (var writer = new StreamWriter(context.HttpContext.Response.Body)) { writer.Write("<div>MyAction 3 OnActionExecuting</div>"); } } }
MyActionFourAttribute拦截器将会声明在子Controller类HomeController的Index方法上:
/// <summary> /// MyActionFourAttribute拦截器将会声明在子Controller类HomeController的Index方法上 /// </summary> public class MyActionFourAttribute : Attribute, IActionFilter { public void OnActionExecuted(ActionExecutedContext context) { using (var writer = new StreamWriter(context.HttpContext.Response.Body)) { writer.Write("<div>MyAction 4 OnActionExecuted</div>"); } } public void OnActionExecuting(ActionExecutingContext context) { using (var writer = new StreamWriter(context.HttpContext.Response.Body)) { writer.Write("<div>MyAction 4 OnActionExecuting</div>"); } } }
然后我们在ASP.NET Core MVC项目中Startup类的ConfigureServices方法中,全局声明MyActionOneAttribute拦截器到项目的所有Controller上:
public void ConfigureServices(IServiceCollection services) { services.AddMvc(options => { options.Filters.Add(typeof(MyActionOneAttribute)); }); }
然后我们定义父Controller类BaseController,它继承于Microsoft.AspNetCore.Mvc.Controller,并声明了MyActionTwoAttribute拦截器:
[MyActionTwo] public class BaseController : Controller { }
然后我们定义子Controller类HomeController,它继承于BaseController,并在类上声明了MyActionThreeAttribute拦截器,Action方法Index上声明了MyActionFourAttribute拦截器:
[MyActionThree] public class HomeController : BaseController { [MyActionFour] public IActionResult Index() { using (var writer = new StreamWriter(HttpContext.Response.Body)) { writer.Write("<div>Index</div>"); } return new EmptyResult(); } }
并且我们在HomeController的Action方法Index中,输出了一个字符串"<div>Index</div>"。
所以现在我们相当于是在子Controller类HomeController的Index方法上,同时声明了MyActionOneAttribute、MyActionTwoAttribute、MyActionThreeAttribute和MyActionFourAttribute四个拦截器,那么这四个拦截器的执行顺序是什么样的呢?
现在我们运行ASP.NET Core MVC项目,在Web浏览器中输出结果如下:
从上图结果中,我们可以看出:
- 最先执行的是全局声明的MyActionOneAttribute拦截器
- 然后执行的是声明在子Controller类HomeController上的MyActionThreeAttribute拦截器
- 接着执行的是声明在父Controller类BaseController上的MyActionTwoAttribute拦截器
- 最后执行的是声明在子Controller类HomeController的Index方法上的MyActionFourAttribute拦截器
所以这个结果证明了声明在子Controller类上的Filter拦截器,要先于声明在父Controller类上的Filter拦截器执行!
【推荐】国内首个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 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2018-04-04 Sql server 使用drop database 语句,无法删除正在使用的数据库的解决办法