我们知道在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拦截器执行的更多相关文章

  1. ASP.NET Core MVC中的IActionFilter.OnActionExecuting方法,可以获取Controller的Action方法参数值

    用过ASP.NET Core MVC中IActionFilter拦截器的开发人员,都知道这是一个非常强大的MVC拦截器.最近才发现IActionFilter的OnActionExecuting方法,甚 ...

  2. ASP.NET Core MVC中的IActionFilter.OnActionExecuted方法执行时,Controller中Action返回的对象是否已经输出到Http Response中

    我们在ASP.NET Core MVC项目中有如下HomeController: using Microsoft.AspNetCore.Mvc; namespace AspNetCoreActionF ...

  3. ASP.NET Core MVC 中的 [Controller] 和 [NonController]

    前言 我们知道,在 MVC 应用程序中,有一部分约定的内容.其中关于 Controller 的约定是这样的. 每个 Controller 类的名字以 Controller 结尾,并且放置在 Contr ...

  4. 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 ...

  5. ASP.NET MVC和ASP.NET Core MVC中获取当前URL/Controller/Action (转载)

    ASP.NET MVC 一.获取URL(ASP.NET通用): [1]获取完整url(协议名+域名+虚拟目录名+文件名+参数) string url=Request.Url.ToString(); [ ...

  6. ASP.NET Core MVC中Controller的Action,默认既支持HttpGet,又支持HttpPost

    我们知道ASP.NET Core MVC中Controller的Action上可以声明HttpGet和HttpPost特性标签,来限制可以访问Action的Http请求类型(GET.POST等). 那 ...

  7. ASP.NET Core MVC中Controller的Action如何直接使用Response.Body的Stream流输出数据

    在ASP.NET Core MVC中,我们有时候需要在Controller的Action中直接输出数据到Response.Body这个Stream流中,例如如果我们要输出一个很大的文件到客户端浏览器让 ...

  8. 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. ...

  9. ASP.NET Core MVC中构建Web API

    在ASP.NET CORE MVC中,Web API是其中一个功能子集,可以直接使用MVC的特性及路由等功能. 在成功构建 ASP.NET CORE MVC项目之后,选中解决方案,先填加一个API的文 ...

随机推荐

  1. Stable Fur Generation on Mesh

    After tested the Maya 2015 XGen Grooming, we dropped it, that's really slow and unstable, totally no ...

  2. 使用vuejs2.0和element-ui 搭建的一个后台管理界面

    说明: 这是一个用vuejs2.0和element-ui搭建的后台管理界面. 相关技术: vuejs2.0:一套构建用户界面的渐进式JavaScript框架,易用.灵活.高效. element-ui: ...

  3. PostgreSQL分页

    转自 https://blog.csdn.net/tomcat_2014/article/details/49947711 如果用过mysql,那么对 select * from xxx limit ...

  4. Python输出和输入

    一.input()函数 在 Python 中,使用内置函数 input()可以接收用户的键盘输入. input()函数的基本用法如 下: variable = input("提示文字") 其中,var ...

  5. Incorrect key file for table错误解决方法

    问题现象: alter table portal_app_xxxx_xxx add devno varchar(64) NOT NULL DEFAULT '' COMMENT '设备机编',add s ...

  6. RHEL/Centos7 安装图形化桌面

    Linux是一个多任务的多用户的操作系统,好多linux爱好者在安装完linux后经常遇到一个问题——没有图形化桌面.今天小编在安装RHEL7的时候,一步留神没有安装图形化桌面,下面分享一下安装图形化 ...

  7. VMare Workstation 安装Ubuntu 虚拟机教程

    1.VMware Workstation,选择左上角文件—新建虚拟机,开始新建一台虚拟机,典型的话许多配置为默认设置,因此,这里我选择自定义安装: 2.机硬件兼容性选择默认即可: 3.客户操作系统选择 ...

  8. LeetCode算法题-Range Sum Query Immutable(Java实现)

    这是悦乐书的第204次更新,第214篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第70题(顺位题号是303).给定整数数组nums,找到索引i和j(i≤j)之间的元素之 ...

  9. java使用elasticsearch实现集群管理

    本篇博客主要是查看集群中的相关信息,具体请看代码和注释 @Test public void test45() throws UnknownHostException{ //1.指定es集群 clust ...

  10. [福大软工] Z班 第2次成绩排行榜

    作业链接 http://www.cnblogs.com/easteast/p/7469291.html 评分细则 本次个人项目分数由三部分组成,分别是 (1)博客 - 20分,分数组成如下: 在文章开 ...