在ASP.NET Core MVC中子類Controller攔截器要先於父類Controller攔截器執行


我們知道在ASP.NET Core MVC中Controller上的Filter攔截器是有執行順序的,那么如果我們在有繼承關系的兩個Controller類上,聲明同一種類型的Filter攔截器,那么是父Controller類的Filter攔截器先執行呢,還是子Controller類的Filter攔截器先執行呢?

 

首先我們新建一個ASP.NET Core MVC項目。

 

然后我們新建四個IActionFilter攔截器:MyActionOneAttribute、MyActionTwoAttribute、MyActionThreeAttribute和MyActionFourAttribute

 

MyActionOneAttribute攔截器將會全局聲明在ASP.NET Core MVC項目的所有Controller上:

/// <summary>
/// MyActionOneAttribute攔截器將會全局聲明在ASP.NET Core MVC項目的所有Controller上
/// </summary>
public class MyActionOneAttribute : Attribute, IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        using (var writer = new StreamWriter(context.HttpContext.Response.Body))
        {
            writer.Write("<div>MyAction 1 OnActionExecuted</div></body></html>");
        }
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        using (var writer = new StreamWriter(context.HttpContext.Response.Body))
        {
            context.HttpContext.Response.ContentType = "text/html";
            context.HttpContext.Response.StatusCode = 200;
            writer.Write("<html><head></head><body><div>MyAction 1 OnActionExecuting</div>");
        }
    }
}

 

MyActionTwoAttribute攔截器將會聲明在父Controller類BaseController上:

/// <summary>
/// MyActionTwoAttribute攔截器將會聲明在父Controller類BaseController上
/// </summary>
public class MyActionTwoAttribute : Attribute, IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        using (var writer = new StreamWriter(context.HttpContext.Response.Body))
        {
            writer.Write("<div>MyAction 2 OnActionExecuted</div>");
        }
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        using (var writer = new StreamWriter(context.HttpContext.Response.Body))
        {
            writer.Write("<div>MyAction 2 OnActionExecuting</div>");
        }
    }
}

 

MyActionThreeAttribute攔截器將會聲明在子Controller類HomeController上:

/// <summary>
/// MyActionThreeAttribute攔截器將會聲明在子Controller類HomeController上
/// </summary>
public class MyActionThreeAttribute : Attribute, IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        using (var writer = new StreamWriter(context.HttpContext.Response.Body))
        {
            writer.Write("<div>MyAction 3 OnActionExecuted</div>");
        }
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        using (var writer = new StreamWriter(context.HttpContext.Response.Body))
        {
            writer.Write("<div>MyAction 3 OnActionExecuting</div>");
        }
    }
}

 

MyActionFourAttribute攔截器將會聲明在子Controller類HomeController的Index方法上:

/// <summary>
/// MyActionFourAttribute攔截器將會聲明在子Controller類HomeController的Index方法上
/// </summary>
public class MyActionFourAttribute : Attribute, IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        using (var writer = new StreamWriter(context.HttpContext.Response.Body))
        {
            writer.Write("<div>MyAction 4 OnActionExecuted</div>");
        }
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        using (var writer = new StreamWriter(context.HttpContext.Response.Body))
        {
            writer.Write("<div>MyAction 4 OnActionExecuting</div>");
        }
    }
}

 

然后我們在ASP.NET Core MVC項目中Startup類的ConfigureServices方法中,全局聲明MyActionOneAttribute攔截器到項目的所有Controller上:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.Filters.Add(typeof(MyActionOneAttribute));
    });
}

 

然后我們定義父Controller類BaseController,它繼承於Microsoft.AspNetCore.Mvc.Controller,並聲明了MyActionTwoAttribute攔截器:

[MyActionTwo]
public class BaseController : Controller
{

}

 

然后我們定義子Controller類HomeController,它繼承於BaseController,並在類上聲明了MyActionThreeAttribute攔截器,Action方法Index上聲明了MyActionFourAttribute攔截器:

[MyActionThree]
public class HomeController : BaseController
{
    [MyActionFour]
    public IActionResult Index()
    {
        using (var writer = new StreamWriter(HttpContext.Response.Body))
        {
            writer.Write("<div>Index</div>");
        }

        return new EmptyResult();
    }
}

並且我們在HomeController的Action方法Index中,輸出了一個字符串"<div>Index</div>"。

 

所以現在我們相當於是在子Controller類HomeController的Index方法上,同時聲明了MyActionOneAttribute、MyActionTwoAttribute、MyActionThreeAttribute和MyActionFourAttribute四個攔截器,那么這四個攔截器的執行順序是什么樣的呢?

 

現在我們運行ASP.NET Core MVC項目,在Web瀏覽器中輸出結果如下:

從上圖結果中,我們可以看出:

  • 最先執行的是全局聲明的MyActionOneAttribute攔截器
  • 然后執行的是聲明在子Controller類HomeController上的MyActionThreeAttribute攔截器
  • 接着執行的是聲明在父Controller類BaseController上的MyActionTwoAttribute攔截器
  • 最后執行的是聲明在子Controller類HomeController的Index方法上的MyActionFourAttribute攔截器

所以這個結果證明了聲明在子Controller類上的Filter攔截器,要先於聲明在父Controller類上的Filter攔截器執行!

 


免責聲明!

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



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