網站首頁 編程語言 正文
過濾器的作用是在 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`,接著才會執行過濾器:同類型的過濾器都會以先進后出的方式執行。
黃色箭頭是正常情況流程
灰色箭頭是異常處理流程
過濾器的作用域與執行順序
過濾器具有三種不同級別的作用域。您可以通過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>(); } }
示例來自于ASP.NET Core MVC 英語文檔
默認執行順序
當管道的某個階段存在多個過濾器時,過濾器執行的默認順序由作用域確定:全局過濾器優先于控制器過濾器,控制器過濾器優先于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://www.cnblogs.com/tdfblog/p/filters-in-aspnet-core-mvc.html
相關推薦
- 2022-04-06 go語言限制協程并發數的方案詳情_Golang
- 2022-11-30 jQuery中隱藏元素的hide方法及說明_jquery
- 2022-11-17 Android使用元數據實現配置信息的傳遞方法詳細介紹_Android
- 2023-01-26 Redis中如何設置日志_Redis
- 2022-06-15 golang中net的tcp服務使用_Golang
- 2023-07-24 uniapp開發小程序端原生導航欄
- 2022-11-05 go?module化?import?調用本地模塊?tidy的方法_Golang
- 2022-06-07 python數組的復制與列表中的pop_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支