標籤:sync wait attr rri control res tin var void
asp.net core MVC 過濾器會在請求管道的各個階段觸發。同一階段又可以註冊多個範圍的過濾器,例如Global範圍,controller範圍等。以ActionFilter為例,我們來看看過濾器的觸發順序。
過濾器可註冊範圍
- 全域:將作用於所有請求的action
- controller:將作用於這個controller下的所有action
- action:作用於單個action
定義過濾器全域
public class GlobalActionFilter : IAsyncActionFilter{ public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegatenext) { var factory = context.HttpContext.RequestServices.GetService<ILoggerFactory>(); var logger = factory.CreateLogger<GlobalActionFilter>(); logger.LogWarning("全域ActionFilter執行之前"); await next(); logger.LogWarning("全域ActionFilter執行之後"); }}
controller(分為註解方式和重寫方式)
註解方式:
public class ControllerActionFilter : ActionFilterAttribute{ public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { var factory = context.HttpContext.RequestServices.GetService<ILoggerFactory>(); var logger = factory.CreateLogger<GlobalActionFilter>(); logger.LogWarning("ControllerActionFilter執行之前"); await next(); logger.LogWarning("ControllerActionFilter執行之後"); }}
重寫方式(在controller內重寫OnActionExecutionAsync)
public override async Task OnActionExecutionAsync(ActionExecutingContext context,ActionExecutionDelegate next){ var logger = _factory.CreateLogger<ValuesController>(); logger.LogWarning("Controller內部重寫的actionFinter執行前"); await next(); logger.LogWarning("Controller內部重寫的actionFinter執行後");}
應用過濾器全域(在Startup中修改)
public void ConfigureServices(IServiceCollection services){ services.AddMvc(o => { o.Filters.Add<GlobalActionFilter>(); });}
controller(重寫方式直接可用不用操作)
[ControllerActionFilter]public class ValuesController : Controller
Action
[HttpGet][ActionActionFilter]public IEnumerable<string> Get()
執行結果
從結果可以看出,Controller重寫 > 全域 > Controller > Action
自訂過濾器執行順序
過濾器的執行順序不是一成不變的,aspNet Core 通過靈活的設計讓我們可以手動自訂過濾器的執行順序。要實現自訂過濾器執行順序則需要實現IOrderedFilter介面,該介面定義一個int類型的Order屬性,這個屬性越大則執行順序越滯後。
實現IOrderFilter介面
public class GlobalActionFilter : IAsyncActionFilter,IOrderedFilter{ public int Order => 0;
繼承Attribute方式直接傳入參數
[ControllerActionFilter(Order =-1)] public class ValuesController : Controller {
[HttpGet][ActionActionFilter(Order =-2)]public IEnumerable<string> Get(){
結果
此時的執行順序:controller內部重寫 > Action > controller > global
解說asp.net core MVC 過濾器的執行順序