ASP.NET Core MVC 过滤器介绍
过滤器的作用是在 Action 方法执行前或执行后做一些加工处理。使用过滤器可以避免Action方法的重复代码,例如,您可以使用异常过滤器合并异常处理的代码。
过滤器如何工作?
过滤器在 MVC Action 调用管道中运行,有时称为过滤器管道。MVC选择要执行的Action方法后,才会执行过滤器管道:

实现
过滤器同时支持同步和异步两种不同的接口定义。您可以根据执行的任务类型,选择同步或异步实现。
同步过滤器定义OnStageExecuting和OnStageExecuted方法,会在管道特定阶段之前和之后运行代码的。例如IActionFilter过滤器,在调用Action方法之前调用OnActionExecuting,在Action方法之回之后调用OnActionExecuted:
public class SampleActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// do something before the action executes
}
public void OnActionExecuted(ActionExecutedContext context)
{
// do something after the action executes
}
}
异步过滤器定义了一个OnStageExecutionAsync方法。该方法提供了FilterTypeExecutionDelegate的委托,当调用该委托时会执行具体管道阶段的工作。例如,ActionExecutionDelegate用于调用Action方法,您可以在调用它之前和之后执行代码。
public class SampleAsyncActionFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(
ActionExecutingContext context,
ActionExecutionDelegate next)
{
// do something before the action executes
await next();
// do something after the action executes
}
}
您可以在单个类中实现多个过滤器接口。例如,ActionFilterAttribute抽象类实现了IActionFilter和IResultFilter,以及与它们对应的异步接口。
提示
您不需要同时实现两种过滤器接口,要么是同步的,要么是异步的。框架首先检查过滤器是否实现了异步接口,如果是,直接执行异步方法。如果不是,它会执行同步接口的方法。如果在一个类上同时实现两种接口,则只会调用异步方法。当使用像ActionFilterAttribute这类抽象类时,您只需要覆盖过滤器的同步方法或异步方法。
## 过滤器类型
ASP.NET Core 有以下五种类型的过滤器,每个过滤器类型在过滤器管道中的不同阶段执行:
- Authorization Filter
授权过滤器 在过滤器管道中第一个执行,通常用于验证当前请求的合法性,不合法后面的管道会直接跳过。它们只有一个Before方法,不像其它大多数过滤器支持前置阶段方法和后置阶段方法。注意,您不要在授权过滤器中抛出异常,因为没有任何代码来处理异常(异常过滤器不处理它们)。 - Resource Filter
资源过滤器是第二个运行,在 Authorization Filter 之后,Model Binding 之前执行。在性能方面,资源过滤器在实现缓存或截断过滤器管道尤为重要。 - Action Filter
使用率最高的过滤器,在调用 Acioin 方法之前和之后执行代码。跟 Resource Filter 很类似,但 Model Binding 在之后执行。 - Exception Filter
用于为应用程序执行异常处理策略。 - Result Filter
当 Action 执行完成后,最后会执行过滤器。用于处理ActionResult结果输出策略。
## 过滤器运行顺序
ASP.NET Core 的每个请求都会先经过已注册的`Middleware`,接着才会执行过滤器:同类型的过滤器都会以先进后出的方式执行。

图片来自 John Wu 的博客
黃色箭头是正常情況流程
灰色箭头是异常处理流程
过滤器的作用域与执行顺序
过滤器具有三种不同级别的作用域。您可以通过Attribute将过滤器注册到指定控制器或 Action 方法;您也可以在Startup类的ConfigureServices方法中将过滤器注册到MvcOptions.Filters的集合中作为全局过滤器(对所有的控制器和Action方法均有效):
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.Filters.Add(new AddHeaderAttribute("GlobalAddHeader",
"Result filter added to MvcOptions.Filters")); // an instance
options.Filters.Add(typeof(SampleActionFilter)); // by type
options.Filters.Add(new SampleGlobalActionFilter()); // an instance
});
services.AddScoped<AddHeaderFilterWithDi>();
}
}
默认执行顺序
当管道的某个阶段存在多个过滤器时,过滤器执行的默认顺序由作用域确定:全局过滤器优先于控制器过滤器,控制器过滤器优先于Action方法过滤器。
以下示例是同步 Action 过滤器调用的顺序:
| 序号 | 过滤器作用域 | 过滤器方法 |
|---|---|---|
| 1 | Global | OnActionExecuting |
| 2 | Controller | OnActionExecuting |
| 3 | Method | OnActionExecuting |
| 4 | Method | OnActionExecuted |
| 5 | Controller | OnActionExecuted |
| 6 | Global | OnActionExecuted |
提示
每个控制器的基类Controller包含OnActionExecuting和OnActionExecuted方法。其中OnActionExecuting在所有过滤器之前调用,OnActionExecuted在所有过滤器之后调用。
覆盖默认执行顺序
您可以通过实现IOrderedFilter接口来覆盖默认的执行顺序。此接口公开了Order属性表示优先级,以确定执行顺序;具有较低Order值的过滤器将在具有较高Order值的过滤器之前执行前置方法;具有较低Order值的过滤器将在具有较高Order值的过滤器之后执行后置方法。
您可以使用构造函数参数设置Order属性:
[MyFilter(Name = "Controller Level Attribute", Order=1)]
如果您将上述示例中 Action 过滤器的Order设置为1,将控制器和全局过滤器的Order属性分别设置为2和3,则执行顺序将与默认相反。
| 序号 | 过滤器作用域 | Order 属性 |
过滤器方法 |
|---|---|---|---|
| 1 | Method | 1 | OnActionExecuting |
| 2 | Controller | 2 | OnActionExecuting |
| 3 | Global | 3 | OnActionExecuting |
| 4 | Global | 3 | OnActionExecuted |
| 5 | Controller | 2 | OnActionExecuted |
| 6 | Method | 1 | OnActionExecuted |
过滤器执行时,Order属性的优先级高于作用域。过滤器首先按Order属性排序,然后再按作用域排序。所有内置过滤器实现IOrderedFilter接口并将Order值默认设置为0;因此,除非设置Order属性为非零值,否则按作用域的优先级执行。
## 总结
今天我们已经了解了关于过滤器基本知识,在下一篇博客中,我们将介绍内置过滤器、过滤的使用、依赖注入、取消与截断等知识,谢谢!
参考资料
- https://blog.johnwu.cc/article/asp-net-core-filters.html
- https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters
转载请注明出处,原文链接:http://www.cnblogs.com/tdfblog/p/filters-in-aspnet-core-mvc.html。
ASP.NET Core MVC 过滤器介绍的更多相关文章
- 解说asp.net core MVC 过滤器的执行顺序
asp.net core MVC 过滤器会在请求管道的各个阶段触发.同一阶段又可以注册多个范围的过滤器,例如Global范围,controller范围等.以ActionFilter为例,我们来看看过滤 ...
- ASP.NET Core MVC 过滤器
参考网址:https://www.cnblogs.com/dotNETCoreSG/p/aspnetcore-4_4_3-filters.html ASP.NET Core有五种类型的过滤器,每个过滤 ...
- Pro ASP.NET Core MVC 第6版 第一章
目录 第一章 ASP.NET Core MVC 的前世今生 ASP.NET Core MVC 是一个微软公司开发的Web应用程序开发框架,它结合了MVC架构的高效性和简洁性,敏捷开发的思想和技术和.N ...
- 使用EF Core+CodeFirst建立ASP.NET Core MVC项目
本篇随笔介绍如何使用.NET Core+EF Core创建Web应用程序 首先借用官网的话简单介绍一下ASP.NET Core ASP.NET Core 是一个跨平台的高性能开源框架,用于生成基于云且 ...
- asp.net core mvc权限控制:权限控制介绍
在进行业务软件开发的时候,都会涉及到权限控制的问题,asp.net core mvc提供了相关特性. 在具体介绍使用方法前,我们需要先了解几个概念: 1,claim:英文翻译过来是声明的意思,一个cl ...
- ASP.NET Core MVC Tag Helpers 介绍
简介 Tag Helpers 提供了在视图中更改和增强现有HTML元素的功能.将它们添加到视图中,会经过Razor模板引擎处理并创建一个HTML,之后再返回给浏览器.有一些Tag Helpers,其实 ...
- asp.net core MVC 全局过滤器之ExceptionFilter异常过滤器(一)
本系类将会讲解asp.net core MVC中的内置全局过滤器的使用,将分为以下章节 asp.net core MVC 过滤器之ExceptionFilter异常过滤器(一) asp.net cor ...
- asp.net core MVC 过滤器之ActionFilter过滤器(二)
本系类将会讲解asp.net core MVC中的内置全局过滤器的使用,将分为以下章节 asp.net core MVC 过滤器之ExceptionFilter过滤器(一) asp.net core ...
- ASP.NET Core MVC – Tag Helpers 介绍
ASP.NET Core Tag Helpers系列目录,这是第一篇,共五篇: ASP.NET Core MVC – Tag Helpers 介绍 ASP.NET Core MVC – Caching ...
随机推荐
- React学习小结(三)
一.React数据的传输 1.属性和状态是react中数据传递的载体 2.属性是声明以后不允许被修改的东西 3.属性只能在组件初始化的时候声明并传入组件内部,并且在组件内部通过this.props获取 ...
- 2017-5-31 VBA设置config sheet 制作工具
最近学习了对单元格式进行设置的两种方式,一个是把一个sheet设置成config的配置,之后把内容读进去:一个是在sheet中读取XML文件. 今天先说说怎么用config来读取数据. 把这一个she ...
- Linux上open-iscsi 的安装,配置和使用
关于open-iscsi open-iscsi是一个实现 RFC3720 iSCSI协议的高性能initiator程序.iSCSI使得访问SAN上的存储不再只能依赖Fibre Channel,也可以通 ...
- ImageView最大高度和宽度失效解决方案
解决方案 做RecyclerView的 item 布局时,用到imageview ,可是图片按原始尺寸显示,不规范. 所以去google了一下imageview的宽高限制,就试了下maxheight/ ...
- js 实现倒计时效果
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 奇妙的 CSS shapes(CSS图形)
CSS 发展到今天已经越来越强大了.其语法的日新月异,让很多以前完成不了的事情,现在可以非常轻松的做到.今天就向大家介绍几个比较新的强大的 CSS 功能: clip-path shape-outsid ...
- caffe源码学习之Proto数据格式【1】
前言: 由于业务需要,接触caffe已经有接近半年,一直忙着阅读各种论文,重现大大小小的模型. 期间也总结过一些caffe源码学习笔记,断断续续,这次打算系统的记录一下caffe源码学习笔记,巩固一下 ...
- JavaScript函数之递归
递归 递归的本质就是使用函数自身来解决问题的思路. 递归的定义(摘): 程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明 ...
- 记一次linux主机名莫名其妙变成了bogon
起因:公司网络接口做了接口认证,虚拟机桥接至物理网卡无法完成认证进行网络访问,无奈之下只能讲虚拟机网络模式更改为NAT模式,更改完成之后进行ssh登录,发现主机名发生了变化. 更改NAT模式之前 [r ...
- 高考志愿填报:java 软件 程序员 目前的就业现状
大约在17年前,也就是2000年,学计算机专业的学生可以有大部分都进入本专业,并且就业非常容易.哪怕只会office套件,想找个工作也很简单.那时候学计算机就是最热门的行业. 那时候,搞Java的还是 ...