【ASP.NET Core】MVC过滤器:运行流程

这篇具有很好参考价值的文章主要介绍了【ASP.NET Core】MVC过滤器:运行流程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

MVC 的过滤器(Filters)也翻译为“筛选器”。但是老周更喜欢翻译为“过滤器”,意思上更好理解。

既然都叫过滤器了,就是在MVC的操作方法调用前后进行特殊处理的类型。比如:

a、此调用是否已授权?

b、在模型绑定之前要不要修改数据源?(可能含有儿童不宜的数据)

c、在调用MVC方法前要不要改一改输入参数?在MVC方法调用之后要不要处理一下结果(加点味精,进一步调味)

d、发生异常后怎么处理?

过滤器可解决上面一堆提问。

在 ASP.NET Core 的 MVC 框架中,所有过滤器都实现共同接口 IFilterMetadata。该接口空空如也,未定义任何成员。说白了,它的用处是作为一种“记号”。你怎么证明你就是过滤器,嗯,看看你实现了 IFilterMetadata 接口没?实现了就认定是过滤器。所以,该接口纯粹是个角色标签。

咱们写代码一般不会实现 IFilterMetadata 接口,毕竟里面什么卵方法都没有,怎么规范类型?因此,过滤器专属命名空间 Microsoft.AspNetCore.Mvc.Filters 下为我们公开了以下接口,方便开发者实现:

1、IAuthorizationFilter:授权过滤器,它的优先级最高,总是最先运行。看看你有没有权限调用 MVC 方法,若没权限,就 See you La La。

2、IResourceFilter:资源过滤器。它在授权过滤成功后、模型绑定前运行。可以检查一下用于绑定的数据,要不要改一下。

3、IActionFilter:操作方法过滤器,就是针对 MVC Action 的。在操作方法运行前后运行,可以用来修改输入参数值。

4、IResultFilter:结果过滤器。当 MVC 操作方法运行成功后就会运行,可以用来修改运行结果。比如加点 HTTP 消息头什么的。

5、IExceptionFilter:当 MVC 操作方法运行过程中发生异常才会运行,无异常就不会运行。

…… 其实还有的,但这里咱们先不提,免得大伙搞得头晕。

 文章来源地址https://www.toymoban.com/news/detail-747582.html

过滤器不止一个,同一类型的过滤还可能有多个,因此,它们就像中间件那样,一个个链接起来,形成下水沟,哦不,是调用管道,或叫调用栈。于是,这就出现谁先运行的问题,虽然上面的介绍有说明,不过那太抽象了。任何编程知识只要能用代码来验证和观察,就不用图表和理论。

下面,咱们实现上述几个接口,然后往控制台上打印一些文本,来看看这些过滤器是怎么运行的。

public class CustAuthFilter : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        Console.WriteLine("授权过滤器运行");
    }
}

public class CustResourceFilter : IResourceFilter
{
    public void OnResourceExecuted(ResourceExecutedContext context)
    {
        Console.WriteLine("资源过滤器 - " + $"{nameof(OnResourceExecuted)}方法运行");
    }

    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        Console.WriteLine("资源过滤器 - " + $"{nameof(OnResourceExecuting)}方法运行");
    }
}

public class CustActionFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        Console.WriteLine("操作过滤器 - " + $"{nameof(OnActionExecuted)}方法运行");
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine("操作过滤器 - " + $"{nameof(OnActionExecuting)}方法运行");
    }
}

public class CustResultFilter : IResultFilter
{
    public void OnResultExecuted(ResultExecutedContext context)
    {
        Console.WriteLine("结果过滤器 - " + $"{nameof(OnResultExecuted)}方法运行");
    }

    public void OnResultExecuting(ResultExecutingContext context)
    {
        Console.WriteLine("结果过滤器 - " + $"{nameof(OnResultExecuting)}方法运行");
    }
}

这里我没有实现异常过滤器,只实现了授权、资源、操作方法、结果这几个有代表性的。

授权过滤器只要实现 OnAuthorization 方法即可。在实现代码中,可以通过 HttpContext 对象查找授权有关的对象,如果确认是没有访问权限的,可以设置一个自己定 Result 让 MVC 操作方法的调用终止。

资源过滤器要实现两个方法:OnResourceExecuting 方法在模型绑定前调用,这时你有机会修改数据源;OnResourceExecuted 方法是在资源过滤之后的其他过滤器运行结束才被调用,即:

ResourceExecuting
    ........ 剩余过滤器.......
ResourceExecuted

Action 过滤器也要实现两个方法:OnActionExecuting 在操作调用前运行;OnActionExecuted 是在操作方法调用后运行。

结果过滤器需要实现两个方法:OnResultExecuting 方法在操作结果执行前调用,这里可以修改 MVC 方法返回的值;OnResultExecuted 方法是在操作结果执行之后调用,一般这里可以改改HTTP向应头、Cookie 什么的。

其实咱们刚实现的过滤器都是同步版本,这些过滤器都有配套的异步版本,接口都是以 IAsync 开头。这里咱们先不用管同步异步,避免搞得复杂了。也不要去理会过滤器是全局的还是局部的,下面咱们统一把它们注册为全局的。配置方法是通过 MVC 选项类的 Filters 集合,把要用的过滤器添加进去即可。

 var builder = WebApplication.CreateBuilder(args);
 builder.Services.AddControllersWithViews(options =>
 {
     // 配置全局过滤器
     options.Filters.Add<CustAuthFilter>();
     options.Filters.Add<CustResourceFilter>();
     options.Filters.Add<CustActionFilter>();
     options.Filters.Add<CustResultFilter>();
 });
 var app = builder.Build();

添加一个“狗头”控制器,用于测试。

public class GouTouController : Controller
{
    public IActionResult Index()
    {
        Console.WriteLine("Index操作运行");
        return View();
    }
}

 

为了防止 ASP.NET Core 应用程序输出的日志干扰咱们查看控制台内容,咱们禁用所有日志输出。打开 appsettings.json 文件,把所有日志类别的记录级别改为 None。

{
  "Logging": {
    "LogLevel": {
      "*": "None"
    }
  },
  "AllowedHosts": "*"
}

星号 * 的意思就是代表所有类别的日志,LogLevel 为 None 就不会输出日志了(貌似有个别日志禁用不了)。

运行程序后,控制台打印出这样的内容:

【ASP.NET Core】MVC过滤器:运行流程

 这个流程现在是不是很清晰了?咱们画图表了,直接这样表达就好:

Author
Resource Executing
    Action Executing
            Action Running
    Action Executed
    Result Executing
            Result Running
    Result Executed
Resource Executed

 

局部过滤器的运行过程与全局过滤器相同,如果局部和全局过滤器同时使用,那会发生什么呢?咱们试试。

接下来我们为授权过滤、资源过滤、操作过滤、结果过滤各创建两个类——用于局部和全局。实际开发中一般不需要这样搞,通常全局和局部写一个类就行,毕竟过滤器类型在全局和局部是通用的。我这里只为了演示。局部过滤器是通过特性类的方式应用到 MVC 方法上的,所以,局部过滤器除了实现过滤器接口,还要从 Attribute 类派生。

1、实现局部、全局授权过滤器。

// 授权过滤器-局部
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class MyAuthorFilterAttribute : Attribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        Console.WriteLine("局部:授权过滤器运行");
    }
}

// 授权过滤器-全局
public class GlobAuthorFilter : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        Console.WriteLine("全局:授权过滤器运行");
    }
}

2、实现局部、全局资源过滤器。

// 资源过滤器-局部
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class MyResourceFilterAttribute : Attribute, IResourceFilter
{
    public void OnResourceExecuted(ResourceExecutedContext context)
    {
        Console.WriteLine("局部:资源过滤器-Executed");
    }

    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        Console.WriteLine("局部:资源过滤器-Executing");
    }
}

// 资源过滤器-全局
public class GlobResourceFilter : IResourceFilter
{
    public void OnResourceExecuted(ResourceExecutedContext context)
    {
        Console.WriteLine("全局:资源过滤器-Executed");
    }

    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        Console.WriteLine("全局:资源过滤器-Executing");
    }
}

3、实现局部、全局操作过滤器。

// 操作过滤器-局部
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class MyActionFilterAttribute : Attribute, IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        Console.WriteLine("局部:操作过滤器-Executed");
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine("局部:操作过滤器-Executing");
    }
}

// 操作过滤器-全局
public class GlobActionFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        Console.WriteLine("全局:操作过滤器-Executed");
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine("全局:操作过滤器-Executing");
    }
}

4、实现局部、全局结果过滤器。

// 结果过滤器-局部
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class MyResultFilterAttribute : Attribute, IResultFilter
{
    public void OnResultExecuted(ResultExecutedContext context)
    {
        Console.WriteLine("局部:结果过滤器-Executed");
    }

    public void OnResultExecuting(ResultExecutingContext context)
    {
        Console.WriteLine("局部:结果过滤器-Executing");
    }
}

// 结果过滤器-全局
public class GlobResultFilter : IResultFilter
{
    public void OnResultExecuted(ResultExecutedContext context)
    {
        Console.WriteLine("全局:结果过滤器-Executed");
    }

    public void OnResultExecuting(ResultExecutingContext context)
    {
        Console.WriteLine("全局:结果过滤器-Executing");
    }
}

 

先注册全局过滤器。

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(options =>
{
    // 添加全局过滤器
    options.Filters.Add<GlobActionFilter>();
    options.Filters.Add<GlobAuthorFilter>();
    options.Filters.Add<GlobResourceFilter>();
    options.Filters.Add<GlobResultFilter>();
});
var app = builder.Build();

局部过滤器以特性方式应用于 MVC 操作方法。

public class SpiderController : ControllerBase
{
    [MyResourceFilter]
    [MyResultFilter]
    [MyActionFilter, MyAuthorFilter]
    public IActionResult Index()
    {
        Console.WriteLine("Index操作被调用");
        return Content("大火烧了毛毛虫");
    }
}

和上一个例子一样,禁用日志输出(appsettings.json文件)。

{
  "Logging": {
    "LogLevel": {
      "*": "None"
    }
  },
  ……
}

程序运行后,控制台打印以下内容:

【ASP.NET Core】MVC过滤器:运行流程

 过滤器按 授权->资源->操作->结果 运行的次序不变。在同种过滤器中,全局过滤器优先运行。

全局授权过滤器
局部授权过滤器
全局资源过滤器 - 前
    局部资源过滤器 - 前
        全局操作过滤器 - 前
            局部操作过滤器 - 前
                【调用 MVC 操作方法】
            局部操作过滤器 - 后
        全局操作过滤器 - 后
        全局结果过滤器 - 前
             局部结果过滤器 - 前
                【执行操作结果】
             局部结果过滤器 - 后
        全局结果过滤器 - 后
    局部资源过滤器 - 后
全局资源过滤器 - 后

 

另外,有一件事要注意:如果你的控制器的基类是 Controller,那么,还有优先更高的 Action Filter。看看 Controller 类它实现了啥接口。

public abstract class Controller : ControllerBase, IActionFilter, IFilterMetadata, IAsyncActionFilter, IDisposable

咱们把刚才的控制器代码改一下,让它继承 Controller 类,并重写 OnActionExecuting、OnActionExecuted 方法。

public class SpiderController : Controller
{
    ……

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine("控制器实现的操作过滤器-Executing");
        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        Console.WriteLine("控制器实现的操作过滤器-Executed");
        base.OnActionExecuted(context);
    }
}

然后再次运行程序,控制台将打印以下内容:

【ASP.NET Core】MVC过滤器:运行流程

看,这个由控制器类实现的 Action 过滤器比全局的还早运行。

 

到了这里,关于【ASP.NET Core】MVC过滤器:运行流程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Fiddler过滤器 Filters 详解

    目录 前言: 一、 Hosts 过滤 (较常用) 二、Client Process 过滤(客户端进程过滤,通过配置只过滤/不过滤哪些进程的请求。用的不多) 三、Request Headers (根据请求头信息进行过滤。常用) 四、Breakpionts 设置断点(很少用,毕竟可以通过 bpu、bpafter以及改写规则js设置断点)

    2024年02月12日
    浏览(49)
  • 【看好了】如何使用fiddler实现手机抓包,Filters过滤器!

    目录 一、Fiddler与其他抓包工具的区别 二、Fiddler的工作原理 三、使用fiddler实现手机抓包 四、Filters过滤器 1、Firebug虽然可以抓包,但是对于分析http请求的详细信息,不够强大。模拟http请求的功能也不够,且firebug常常是需要“无刷新修改”,如果刷新了页面,所有的修改都

    2024年02月09日
    浏览(54)
  • 异常过滤器—MVC中异常过滤器使用

    异常过滤器( Exception Filters )是 ASP.NET Core 中用于处理全局异常的机制。它们允许你在发生异常时捕获、处理和记录异常,并提供自定义的异常处理逻辑。异常过滤器在整个应用程序范围内生效,可以用于处理各种异常情况。用于实现常见的错误处理策略,没有之前和之后事

    2024年02月13日
    浏览(60)
  • 操作过滤器—MVC中使用操作过滤器实现JWT权限认证

    上一篇文章分享了授权过滤器实现JWT进行鉴权,文章链接:授权过滤器—MVC中使用授权过滤器实现JWT权限认证,接下来将用操作过滤器实现昨天的JWT鉴权。 ​ 与授权过滤器大部分一样,只是执行的时机和继承的接口有所不同。操作过滤器是在Action执行的前和后进行调用执行

    2024年02月13日
    浏览(52)
  • 结果过滤器—MVC项目中结果过滤器(Result Filter)使用

    结果过滤器( ResultFilter ),是对执行的Action结果进行处理的一种AOP思想,适用于任何需要直接环绕 View 或格式化处理的逻辑。结果过滤器可以 替换或更改 Action 结果 。在 IActionResult 执行的前后执行,使用它能够控制Action的执行结果,比如:格式化结果等。需要注意的是,它只

    2024年02月12日
    浏览(55)
  • 资源过滤器—MVC中使用资源过滤器实现不执行Action方法体读取缓存信息返回

    上两篇文章分享了过滤器实现JWT进行鉴权,分别是通过授权过滤器和操作过滤器实现,这两个过滤器也是最常用的。文章链接:授权过滤器—MVC中使用授权过滤器实现JWT权限认证,操作过滤器—MVC中使用操作过滤器实现JWT权限认证,接下来将简单的谈谈资源过滤器在MVC中如何

    2024年02月13日
    浏览(55)
  • Spring MVC获取参数和自定义参数类型转换器及编码过滤器

    目录   一、使用Servlet原生对象获取参数 1.1 控制器方法 1.2 测试结果 二、自定义参数类型转换器 2.1 编写类型转换器类 2.2 注册类型转换器对象  2.3 测试结果  三、编码过滤器 3.1 JSP表单 3.2 控制器方法 3.3 配置过滤器 3.4 测试结果  往期专栏文章相关导读  1. Maven系列专

    2024年02月10日
    浏览(65)
  • springbboot拦截器,过滤器,监听器及执行流程

    过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前 请求按照上图进入conteoller后执行完再返回 过滤器是Servlet规范中定义的一种组件,可以用于在请求进入Web应用程序之前或响应离开Web应用程序之前对请

    2024年02月13日
    浏览(43)
  • ASP.NET Core MVC -- 将视图添加到 ASP.NET Core MVC 应用

    右键单击“视图”文件夹,然后单击“添加”“新文件夹”,并将文件夹命名为“HelloWorld”。 右键单击“Views/HelloWorld”文件夹,然后单击“添加”“新项”。 在“添加新项 - MvcMovie”对话框中: 在右上角的搜索框中,输入“视图” 选择“Razor 视图 - 空” 保持“名称”框的

    2024年02月13日
    浏览(91)
  • ASP.NET Core MVC -- 入门

     带有 ASP.NET 和 Web 开发工作负载的Visual Studio Visual Studio Code Visual Studio Code 用于 Visual Studio Code 的 C#(最新版本) .NET 7.0 SDK  ctrl + F5 (开始执行,不调试) 在代码工作区间文件夹路径下打开终端运行下面的命令  通过运行以下命令来信任 HTTPS 开发证书: 编译运行

    2024年02月11日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包