首頁 > 軟體

ASP.NET Core MVC中過濾器工作原理介紹

2022-02-21 13:01:55

過濾器的作用是在 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抽象類實現了IActionFilterIResultFilter,以及與它們對應的非同步介面。

提示您不需要同時實現兩種過濾器介面,要麼是同步的,要麼是非同步的。框架首先檢查過濾器是否實現了非同步介面,如果是,直接執行非同步方法。如果不是,它會執行同步介面的方法。如果在一個類上同時實現兩種介面,則只會呼叫非同步方法。當使用像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 過濾器呼叫的順序:

序號過濾器作用域過濾器方法
1GlobalOnActionExecuting
2ControllerOnActionExecuting
3MethodOnActionExecuting
4MethodOnActionExecuted
5ControllerOnActionExecuted
6GlobalOnActionExecuted

提示每個控制器的基礎類別Controller包含OnActionExecutingOnActionExecuted方法。其中OnActionExecuting在所有過濾器之前呼叫,OnActionExecuted在所有過濾器之後呼叫。

覆蓋預設執行順序

您可以通過實現IOrderedFilter介面來覆蓋預設的執行順序。此介面公開了Order屬性表示優先順序,以確定執行順序;具有較低Order值的過濾器將在具有較高Order值的過濾器之前執行前置方法;具有較低Order值的過濾器將在具有較高Order值的過濾器之後執行後置方法。
您可以使用建構函式引數設定Order屬性:

[MyFilter(Name = "Controller Level Attribute", Order=1)]

如果您將上述範例中 Action 過濾器的Order設定為1,將控制器和全域性過濾器的Order屬性分別設定為2和3,則執行順序將與預設相反。

序號過濾器作用域Order 屬性過濾器方法
1Method1OnActionExecuting
2Controller2OnActionExecuting
3Global3OnActionExecuting
4Global3OnActionExecuted
5Controller2OnActionExecuted
6Method1OnActionExecuted

過濾器執行時,Order屬性的優先順序高於作用域。過濾器首先按Order屬性排序,然後再按作用域排序。所有內建過濾器實現IOrderedFilter介面並將Order值預設設定為0;因此,除非設定Order屬性為非零值,否則按作用域的優先順序執行。

到此這篇關於ASP.NET Core MVC中過濾器工作原理的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com