• 在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拦截器执行!

  • 相关阅读:
    android常用组件
    android button点击效果
    service+activity
    收藏
    c++
    工厂模式
    lr常遇到一些问题
    lr介绍
    ((1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(6) NOT NULL)' at line 1"))
    mysqlclient 1.4.0 or newer is required; you have 0.10.0
  • 原文地址:https://www.cnblogs.com/OpenCoder/p/10656560.html
Copyright © 2020-2023  润新知