在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 = ;
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拦截器执行!
在ASP.NET Core MVC中子类Controller拦截器要先于父类Controller拦截器执行的更多相关文章
- ASP.NET Core MVC中的IActionFilter.OnActionExecuting方法,可以获取Controller的Action方法参数值
用过ASP.NET Core MVC中IActionFilter拦截器的开发人员,都知道这是一个非常强大的MVC拦截器.最近才发现IActionFilter的OnActionExecuting方法,甚 ...
- ASP.NET Core MVC中的IActionFilter.OnActionExecuted方法执行时,Controller中Action返回的对象是否已经输出到Http Response中
我们在ASP.NET Core MVC项目中有如下HomeController: using Microsoft.AspNetCore.Mvc; namespace AspNetCoreActionF ...
- ASP.NET Core MVC 中的 [Controller] 和 [NonController]
前言 我们知道,在 MVC 应用程序中,有一部分约定的内容.其中关于 Controller 的约定是这样的. 每个 Controller 类的名字以 Controller 结尾,并且放置在 Contr ...
- 006.Adding a controller to a ASP.NET Core MVC app with Visual Studio -- 【在asp.net core mvc 中添加一个控制器】
Adding a controller to a ASP.NET Core MVC app with Visual Studio 在asp.net core mvc 中添加一个控制器 2017-2-2 ...
- ASP.NET MVC和ASP.NET Core MVC中获取当前URL/Controller/Action (转载)
ASP.NET MVC 一.获取URL(ASP.NET通用): [1]获取完整url(协议名+域名+虚拟目录名+文件名+参数) string url=Request.Url.ToString(); [ ...
- ASP.NET Core MVC中Controller的Action,默认既支持HttpGet,又支持HttpPost
我们知道ASP.NET Core MVC中Controller的Action上可以声明HttpGet和HttpPost特性标签,来限制可以访问Action的Http请求类型(GET.POST等). 那 ...
- ASP.NET Core MVC中Controller的Action如何直接使用Response.Body的Stream流输出数据
在ASP.NET Core MVC中,我们有时候需要在Controller的Action中直接输出数据到Response.Body这个Stream流中,例如如果我们要输出一个很大的文件到客户端浏览器让 ...
- 008.Adding a model to an ASP.NET Core MVC app --【在 asp.net core mvc 中添加一个model (模型)】
Adding a model to an ASP.NET Core MVC app在 asp.net core mvc 中添加一个model (模型)2017-3-30 8 分钟阅读时长 本文内容1. ...
- ASP.NET Core MVC中构建Web API
在ASP.NET CORE MVC中,Web API是其中一个功能子集,可以直接使用MVC的特性及路由等功能. 在成功构建 ASP.NET CORE MVC项目之后,选中解决方案,先填加一个API的文 ...
随机推荐
- Openlayer3中应用的技术
ol3-ext有很多很丰富的效果,可以不用重复造轮子,ol3-ext示例大全:http://viglino.github.io/ol3-ext/ 在本次项目中使用到了ol3-ext的两个功能:图层管理 ...
- Android为TV端助力 很详细的序列化过程Parcelable
直接上代码:注释都写的很清楚了. public class Entry implements Parcelable{ public int userID; public String username ...
- Multithreading C++ Out of Core Sotring for Massive Data|多线程C++的大规模数据外部排序
先说一下,这个其实是我为实现PantaRay或者是类似Dreamworks的Out of Core点云GI的技术储备,为大规模点云光线跟踪所准备的第一步.在实际的应用中,int类型会被64bit的ui ...
- Kotlin入门(21)活动页面的跳转处理
Activity的活动页面跳转是App最常用的功能之一,在前几章的demo源码中便多次见到了,常常是点击界面上的某个按钮,然后跳转到与之对应的下一个页面.对于App开发者来说,该功能的实现非常普通,使 ...
- RMAN restore fails with ORA-01180: can not create datafile 1
最近在验证.测试备份有效性时,遇到了"ORA-01180: can not create datafile 1"这个错误,顺便结合metalink的官方文档"RMAN ...
- java笔记----常见的异常
常见的可控异常 运行时的异常 异常信息的获取
- shell编程—简单的使用(二)
使用shell编辑.sh使其输出hello tynam 1.新建一个.sh文件,然后进行编辑 vi hello_tynam.sh 2.进行编辑,先按i键进行激活,然后输入echo hello tyna ...
- 深入了解IOC
老师在简书写的一篇博客 https://www.jianshu.com/p/79f8331e1f24
- Vmware ESXi日志文件存放目录地址
有时候我们需要查看虚拟服务端突然宕机的原因,就需要来查看这些日志 ESXi 通过使用 syslog 功能,在日志文件中记录主机活动. 组件 位置 用途 VMkernel /var/log/vmkern ...
- Xmanager power suit 6 最新版注册激活
Xmanager Power Suit 6.0.0012 最新版注册激活,长期更新 操作步骤 Xmanger Power Suit 官方 其实有两种 .exe 文件,一个是用于试用的,在注册的时候不能 ...