解說asp.net core MVC 過濾器的執行順序


asp.net core MVC 過濾器會在請求管道的各個階段觸發。同一階段又可以注冊多個范圍的過濾器,例如Global范圍,controller范圍等。以ActionFilter為例,我們來看看過濾器的觸發順序。

過濾器可注冊范圍

  • 全局:將作用於所有請求的action
  • controller:將作用於這個controller下的所有action
  • action:作用於單個action

定義過濾器

全局

public class GlobalActionFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate
next)
    {
        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屬性,這個屬性越大則執行順序越滯后。

實現IOrderedFilter接口

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM