我们知道在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. 数据库连接池(基于MySQL数据库)

    使用JDBC是怎么保证数据库客户端和数据库服务端进行连接的? 通过代码: conn=DriverManager.getConnection(url, username, password); JDBC ...

  2. 计算机网络TCP“三次握手”

    终于有时间写这篇文章了,最近真的比较忙! TCP协议  之 “三次握手” 引言:我们知道,TCP是面向连接的协议(相较于UDP无连接的协议),会在传送数据之前先在 发送端 & 接收端 之间建立 ...

  3. Android getprop 读取的属性哪里来的?

    Android  getprop 和  setprop 可以对系统属性进行读取和设置. 通过串口执行以下 geyprop    打印出来的属性让你一目了然. 属性出来了,但是在哪里设置的呢,这里有两个 ...

  4. Response()的对象

    addCookie(Cookie cookie):这个方法是向Response容器中添加一个Cookie,然后服务器容器会自动的将这个Cookie回写给客户机的,至于Cookie的相关知识我们会在后面 ...

  5. Spring入门详细教程(四)

    前言 本篇紧接着spring入门详细教程(三),建议阅读本篇前,先阅读第一篇,第二篇以及第三篇.链接如下: Spring入门详细教程(一) https://www.cnblogs.com/jichi/ ...

  6. SQL Server Browser探究

    一.官网关于SQL SERVER Browser服务的解释(谷歌翻译后稍作修改的): https://docs.microsoft.com/en-us/sql/tools/configuration- ...

  7. 高通平台如何使用QPST抓DUMP

    一 :确认手机状态 手机系统死机白屏后,使用USB线 连接手机和计算机.打开计算机设备管理器 ,当其中与手机相关的端口只有DIAG 口 项(9006端口)时,表明手机处于DUMP 模式,可以抓DUMP ...

  8. zabbix 添加自动发现端口并监控

    最近在部署zabbix监控  有些服务器上开启的服务端口非常多  如果一个个添加监控会很繁琐,于是想到了自动发现规则  自动发现服务器上的服务端口并进行监控. 在zabbix客户端服务器上进行操作 1 ...

  9. linux中如何查看进程的启动时间

    ps -p PID -o lstart 其中PID是进程的pid [root@lvs-a logs]# -o lstart STARTED Tue Oct ::

  10. C#深度学习のTask(基于任务的异步模型)

    一.Task关键字解释 Task 类的表示的单个操作不会返回一个值,通常以异步方式执行. Task 对象是一种的中心思想 基于任务的异步编程模式 首次引入.NET Framework 4 中. 因为由 ...