ASP.NET Core 中的五种过滤器

news2024/11/25 20:46:59

ASP.NET Core 中的五种过滤器

  • 前言
  • 一、过滤器介绍
    • 1.五种过滤器
      • (1)IActionFilter
      • (2)IAuthorizationFilter
      • (3)IExceptionFilter
      • (4)IResourceFilter
      • (5)IResultFilter
    • 2.另外两种过滤器
      • (1)IOrderedFilter
      • (2)IPageFilter
    • 3.三个特性
      • (1)ActionFilterAttribute
      • (2)ExceptionFilterAttribute
      • (3)ResultFilterAttribute
  • 二、过滤器演示代码
    • 1.实现接口
      • (1)ActionFilter1Attribute.cs
      • (2)ActionFilter2Attribute.cs
      • (3)AuthorizationFilterAttribute.cs
      • (4)ExecptionFilter.cs
      • (5)ResourceFilterAttribute.cs
      • (6)ResultFilter1Attribute.cs
      • (7)综合测试
    • 2.继承类
      • (1)LogActionFilter.cs
      • (2)ResultFilter.cs


前言

👨‍💻👨‍🌾📝记录学习成果,以便温故而知新

本文以命名空间Microsoft.AspNetCore.Mvc.Filters下的过滤器学习的过程做一个记录。广大网友们都说是过滤器,Java里貌似也说是过滤器,所以就顺着大家叫了。但是官网上却是叫“筛选器”。

Microsoft.AspNetCore.Mvc.Filters 命名空间官网:https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.mvc.filters?view=aspnetcore-7.0

讲实话,微软的官网现在感觉有点凌乱,有些看似官网的却是志愿者还是啥的写的内容。所以如果有什么差错还请谅解。


一、过滤器介绍

1.五种过滤器

广大网友们所说的五种过滤器,当然它们都有对应的异步过滤器。由于学习是循序渐进的,先学习同步的,等掌握好了以后再去学习异步的。

(1)IActionFilter

环绕操作执行的筛选器。

两个方法:

1.OnActionExecuted(ActionExecutedContext)

在操作执行后、操作结果之前调用。

2.OnActionExecuting(ActionExecutingContext)

在操作执行之前调用,在模型绑定完成后调用。

(2)IAuthorizationFilter

确认请求授权的筛选器。

一个方法:

OnAuthorization(AuthorizationFilterContext)

在筛选器管道的早期调用,以确认请求是否已获得授权。

(3)IExceptionFilter

在操作引发 Exception后运行的筛选器。

一个方法:

OnException(ExceptionContext)

在操作引发 Exception后调用 。

(4)IResourceFilter

包含模型绑定执行的筛选器、操作 (和筛选器) 以及操作结果 (和筛选器) 。

两个方法:

1.OnResourceExecuted(ResourceExecutedContext)

执行资源筛选器。 在执行管道的其余部分后调用。

2.OnResourceExecuting(ResourceExecutingContext)

执行资源筛选器。 在执行管道的其余部分之前调用。

(5)IResultFilter

包含操作执行结果的筛选器已成功从操作返回。

IResultFilter 如果授权筛选器或资源筛选器使请求短路以阻止操作的执行,则不会执行 和 IAsyncResultFilter 实例。 IResultFilter. IResultFilter 在异常筛选器通过生成操作结果处理异常的情况下,也不会执行 和 IAsyncResultFilter 实现。

两个方法:

1.OnResultExecuted(ResultExecutedContext)

在操作结果执行之后调用。

2.OnResultExecuting(ResultExecutingContext)

在操作结果执行之前调用。

2.另外两种过滤器

官网中还有另外两种过滤器,不知道广大网友为什么不介绍,只能揣测是不常用。简单介绍如下:

(1)IOrderedFilter

一个筛选器,指定它应运行的相对顺序。

(2)IPageFilter

一个筛选器,用于包围页面处理程序方法的执行。 仅当对处理程序的类型进行修饰时,才会执行此筛选器,而不是在单个处理程序方法上执行。

3.三个特性

很奇怪的是看到很多网友介绍的文章在定义过滤器特性时都没有继承现成的特性,而是实现的接口。

(1)ActionFilterAttribute

异步包围操作的执行和操作结果的抽象筛选器。 子类应替代 、 OnActionExecuted(ActionExecutedContext) 或 OnActionExecutionAsync(ActionExecutingContext, ActionExecutionDelegate) (但不替代OnActionExecutionAsync(ActionExecutingContext, ActionExecutionDelegate)OnActionExecuting(ActionExecutingContext))以及其他两个之一。 同样,子类应替代 、 OnResultExecuted(ResultExecutedContext) 或 OnResultExecutionAsync(ResultExecutingContext, ResultExecutionDelegate) (但不能OnResultExecutionAsync(ResultExecutingContext, ResultExecutionDelegate))OnResultExecuting(ResultExecutingContext)以及其他两个之一。

(2)ExceptionFilterAttribute

在操作引发 Exception后异步运行的抽象筛选器。 子类必须替代 或,OnExceptionAsync(ExceptionContext)但不能同时重写OnException(ExceptionContext)两者。

我再次确认了上面这段的引用,官网是:
在这里插入图片描述
只能无语(我竟无言以对)!!!

(3)ResultFilterAttribute

异步包围操作结果执行的抽象筛选器。 子类必须替代 、 OnResultExecuted(ResultExecutedContext) 或 OnResultExecutionAsync(ResultExecutingContext, ResultExecutionDelegate) (但不能OnResultExecutionAsync(ResultExecutingContext, ResultExecutionDelegate)替代OnResultExecuting(ResultExecutingContext))和另外两个之一。

以上内容看似洋洋洒洒,实际上主要来源于官网。对于这些知识的定义,也只能相信官网,不可能自己发挥的。下面是代码演示,就有了发挥的空间。

二、过滤器演示代码

本文的演示环境是Win10,目标框架是.NET Core 2.1,建的是ASP.NET Core Web 应用程序。不同的环境可能会有差别。

1.实现接口

(1)ActionFilter1Attribute.cs

namespace TestFilter.Filter
{
    public class ActionFilter1Attribute : Attribute, IActionFilter
    {
        public void OnActionExecuted(ActionExecutedContext context)
        {
            Debug.WriteLine("ActionFilter1Attribute OnActionExecuted");
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            Debug.WriteLine("ActionFilter1Attribute OnActionExecuting");
        }
    }
}

(2)ActionFilter2Attribute.cs

namespace TestFilter.Filter
{
    public class ActionFilter2Attribute : Attribute, IActionFilter
    {
        public void OnActionExecuted(ActionExecutedContext context)
        {
            Debug.WriteLine("ActionFilter2Attribute OnActionExecuted");
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            Debug.WriteLine("ActionFilter2Attribute OnActionExecuting");
        }
    }
}

定义了两个过滤器是想看同时注册时的调用顺序,如下测试代码:

// GET: api/User/ShowAction1
[HttpGet("ShowAction1")]
[ActionFilter1, ActionFilter2]
public IActionResult ShowAction1()
{
    ContentResult cr = new ContentResult();
    cr.Content = "ShowAction1";
    return cr;
}

控制台输出:
在这里插入图片描述
交换一下过滤器的顺序的代码:

// GET: api/User/ShowAction2
[HttpGet("ShowAction2")]
[ActionFilter2, ActionFilter1]
public IActionResult ShowAction2()
{
    ContentResult cr = new ContentResult();
    cr.Content = "ShowAction2";
    return cr;
}

控制台输出:
在这里插入图片描述
两张截图对比一下,结果很清晰的,所以也用不着总结了。

这里是把特性加在方法上,是给单个方法注册过滤器,下面类似情况不再重复说明。

(3)AuthorizationFilterAttribute.cs

确认授权过滤器特性定义了一个属性,是像简单演示一下权限是如何传参的。记得Java的shiro框架中logical来说明权限数组是“与”逻辑还是“或”逻辑,这里就不细说了,只要明白套路就行。所谓“运用之妙,存乎一心”。

namespace TestFilter.Filter
{
    public class AuthorizationFilterAttribute : Attribute, IAuthorizationFilter
    {
        /// <summary>
        /// 权限
        /// </summary>
        private string[] Privilege { get; set; }

        public AuthorizationFilterAttribute(params string[] privilege)
        {
            Privilege = privilege;
        }

        public void OnAuthorization(AuthorizationFilterContext context)
        {
            Debug.WriteLine("权限数量:" + Privilege.Length);
            Debug.WriteLine("AuthorizationFilter OnAuthorization");
        }
    }
}

测试代码如下:

// GET: api/User/ShowAuthorization1
[HttpGet("ShowAuthorization1")]
[AuthorizationFilter]
public IActionResult ShowAuthorization1()
{
    ContentResult cr = new ContentResult();
    cr.Content = "Authorization1";
    return cr;
}

控制台输出如图:
在这里插入图片描述
又一段测试代码:

// GET: api/User/ShowAuthorization2
[HttpGet("ShowAuthorization2")]
 [AuthorizationFilter("Admin", "User")]
 public IActionResult ShowAuthorization2()
 {
     ContentResult cr = new ContentResult();
     cr.Content = "Authorization2";
     return cr;
 }

控制台输出:
在这里插入图片描述
这里用可变长参数给特性传参,模拟传"Admin"与"User"两类权限。

(4)ExecptionFilter.cs

由于异常处理通常是全局的,所以就没有定义成特性。

namespace TestFilter.Filter
{
    public class ExecptionFilter : IExceptionFilter
    {
        public void OnException(ExceptionContext context)
        {
            Debug.WriteLine(context.Exception);

            context.Result = new ObjectResult("ExceptionHandled ");
            context.ExceptionHandled = true;
        }
    }
}

在Startup.cs文件中ConfigureServices方法里注册全局过滤器

services.AddMvc(option => {
    option.Filters.Add<ExecptionFilter>();//全局异常
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

测试代码如下:

// GET: api/User/ShowException
[HttpGet("ShowException")]
public IActionResult ShowException()
{
    throw new Exception("ShowException");
}

控制台输出如图:
在这里插入图片描述
在集成开发环境中要点一下“继续”才能看到控制台的输出,否则流程会被阻塞。

(5)ResourceFilterAttribute.cs

namespace TestFilter.Filter
{
    public class ResourceFilterAttribute : Attribute, IResourceFilter

    {
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            Debug.WriteLine("ResourceFilterAttribute OnResourceExecuted");
        }

        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            Debug.WriteLine("ResourceFilterAttribute OnResourceExecuting");
        }
    }
}

测试代码如下:

// GET: api/User/ShowResource
[HttpGet("ShowResource")]
[ResourceFilter]
public IActionResult ShowResource()
{
    ContentResult cr = new ContentResult();
    cr.Content = "ShowResource";
    return cr;
}

控制台输出如图:
在这里插入图片描述

(6)ResultFilter1Attribute.cs

namespace TestFilter.Filter
{
    public class ResultFilter1Attribute : Attribute, IResultFilter
    {
        public void OnResultExecuted(ResultExecutedContext context)
        {
            Debug.WriteLine("ResultFilterAttribute OnResultExecuted");
        }

        public void OnResultExecuting(ResultExecutingContext context)
        {
            Debug.WriteLine("ResultFilterAttribute OnResultExecuting");
        }
    }
}

测试代码如下:

// GET: api/User/ShowResult1
[HttpGet("ShowResult1")]
[ResultFilter1]
public IActionResult ShowResult1()
{
    ContentResult cr = new ContentResult();
    cr.Content = "ShowResult1";
    return cr;
}

在这里插入图片描述

(7)综合测试

测试代码:

// GET: api/User/Comprehensive
[HttpGet("Comprehensive")]
[ActionFilter1]
[AuthorizationFilter]
[ResourceFilter]
[ResultFilter1]
public IActionResult Comprehensive()
{
    ContentResult cr = new ContentResult();
    cr.Content = "Comprehensive";
    return cr;
}

控制台输出如图:
在这里插入图片描述
这张截图很能说明各种过滤器的执行顺序。
异常过滤器会阻断一些过滤器的执行,有兴趣的自己可以去测试一下。

2.继承类

(1)LogActionFilter.cs

这段代码来源于文章了解操作筛选器 (C#)“创建日志操作筛选器”一节,感觉很有趣,就借用了。

namespace TestFilter.Filter
{
    public class LogActionFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            Log("OnActionExecuting", filterContext.RouteData);
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            Log("OnActionExecuted", filterContext.RouteData);
        }

        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            Log("OnResultExecuting", filterContext.RouteData);
        }

        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            Log("OnResultExecuted", filterContext.RouteData);
        }


        private void Log(string methodName, RouteData routeData)
        {
            var controllerName = routeData.Values["controller"];
            var actionName = routeData.Values["action"];
            var message = String.Format("{0} controller:{1} action:{2}", methodName, controllerName, actionName);
            Debug.WriteLine(message, "Action Filter Log");
        }
    }
}

测试代码:

namespace TestFilter.Controllers.Api
{
    [Route("api/[controller]")]
    [ApiController]
    [LogActionFilter]
    public class RoleController : ControllerBase
    {
        // GET: api/Role/Show
        [HttpGet("Show")]
        public IActionResult Show()
        {
            ContentResult cr = new ContentResult();
            cr.Content = "Show";
            return cr;
        }
    }
}

控制台输出如图:
在这里插入图片描述
这里的代码一是想介绍一下在类上注册过滤器;二是简单介绍获取方法的信息,其实还可以获取方法的传参与返回,限于篇幅就不展开了;三是想展示一下ActionFilterAttribute类可以覆盖的内容。

(2)ResultFilter.cs

namespace TestFilter.Filter
{
    public class ResultFilter : ResultFilterAttribute
    {
        public override void OnResultExecuted(ResultExecutedContext context)
        {
            Debug.WriteLine("ResultFilter OnResultExecuted");
        }

        public override void OnResultExecuting(ResultExecutingContext context)
        {
            Debug.WriteLine("ResultFilter OnResultExecuting");
        }
    }
}

测试代码:

// GET: api/User/ShowResult2
[HttpGet("ShowResult2")]
[ResultFilter]
public IActionResult ShowResult2()
{
    ContentResult cr = new ContentResult();
    cr.Content = "ShowResult2";
    return cr;
}

控制台输出如图:
在这里插入图片描述
这里也是两个方法,没有发现明显区别。

因为考虑到异常一般是全局处理,所以没有研究ExceptionFilterAttribute,感觉如果项目定义自己的异常体系倒是有必要针对不同异常来做处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1122943.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux常用命令——clock命令

在线Linux命令查询工具 clock 用于调整 RTC 时间。 补充说明 clock命令用于调整 RTC 时间。 RTC 是电脑内建的硬件时间&#xff0c;执行这项指令可以显示现在时刻&#xff0c;调整硬件时钟的时间&#xff0c;将系统时间设成与硬件时钟之时间一致&#xff0c;或是把系统时间…

【刷题-牛客】出栈、入栈的顺序匹配 (代码+动态演示)

【刷题-牛客】出栈、入栈的顺序匹配 (代码动态演示) 文章目录 【刷题-牛客】出栈、入栈的顺序匹配 (代码动态演示) 解题思路 动图演示完整代码多组测试 &#x1f497;题目描述 &#x1f497;: 输入两个整数序列&#xff0c;第一个序列表示栈的压入顺序&#xff0c;请判断第二个…

C++标准模板(STL)- 类型支持 (运行时类型识别,bad_typeid,bad_cast )

运行时类型识别 定义于头文件 <typeinfo> 当 typeid 表达式中的实参为空值时抛出的异常 std::bad_typeid class bad_typeid : public std::exception; 此类型的异常在应用 typeid 运算符到多态类型的空指针值时抛出。 成员函数 (构造函数) 构造新的 bad_typeid 对象 (…

如何正确维护实验室超声波清洗机

实验室一直被视作一个严谨且严肃的场所&#xff0c;在其中所做的试验都需要遵照一定流程&#xff0c;所用的设备也经过了细致化挑选&#xff0c;例如实验室超声波清洗机&#xff0c;其性能远强于普通类别的清洗机。专门负责采购的实验室人员&#xff0c;通常会对质量优服务好的…

Auth.js:多合一身份验证解决方案 | 开源日报 No.60

nodejs/node Stars: 96.2k License: NOASSERTION Node.js 是一个开源的、跨平台的 JavaScript 运行时环境。它具有以下关键特性和核心优势&#xff1a; 强大&#xff1a;Node.js 提供了强大且高效的服务器端运行能力&#xff0c;可以处理并发请求&#xff0c;并支持异步编程…

[CSP-S 2023] 种树 —— 二分+前缀和

This way 题意&#xff1a; 一开始以为是水题&#xff0c;敲了一个二分贪心检查的代码&#xff0c;20分。发现从根往某个节点x走的时候&#xff0c;一路走来的子树上的节点到已栽树的节点的距离会变短&#xff0c;那么并不能按照初始情况贪心。 于是就想着检查时候用线段树…

Notepad++正则查询替换操作

Notepad编辑器查找功能非常强大&#xff0c;本处记录一些实战中常用到复杂查询替换操作。 注意&#xff1a;如果是重要文件&#xff0c;替换操作前最好备份&#xff1b;当前一个操作后也可以用ctrlz恢复。 查找重复行 用查找(ctrlf)功能&#xff0c;用正则表达式模式匹配。 查…

基于SSM的电子设备销售网站的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

C# Onnx Yolov8 Detect 戴安全帽检测

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;namespace Onnx…

基于SSM的图书商城网站设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

面试题:说一下Redis中有哪些阻塞点以及如何解决?

文章目录 前言有哪些影响redis性能的因素客户端的阻塞磁盘带来的阻塞主从节点带来的阻塞切片集群的阻塞异步机制解决阻塞异步是如何进行的异步删除lazy-free小结 Redis 中的优秀设计有很多&#xff0c;今天我们一起来聊聊群友刷题遇到的&#xff1a;“Redis的异步机制 —— red…

网络协议--动态选路协议

10.1 引言 在前面各章中&#xff0c;我们讨论了静态选路。在配置接口时&#xff0c;以默认方式生成路由表项&#xff08;对于直接连接的接口&#xff09;&#xff0c;并通过route命令增加表项&#xff08;通常从系统自引导程序文件&#xff09;&#xff0c;或是通过ICMP重定向…

[SQL开发笔记]SELECT DISTINCT语句:返回唯一不同的值

一、功能描述&#xff1a; 使用场景&#xff1a;在表中&#xff0c;一个列可能会包含多个重复值&#xff0c;希望仅仅列出不同&#xff08;distinct&#xff09;的值&#xff0c;我们需要怎么办呢&#xff1f;可以SELECT DISTINCT语句用于返回唯一不同的值 二、SELECT Distinc…

【Unity ShaderGraph】| 快速制作一个 钛金化不锈钢效果

前言 本文将使用ShaderGraph制作一个 钛金化不锈钢 效果&#xff0c;可以直接拿到项目中使用。对ShaderGraph还不了解的小伙伴可以参考这篇文章&#xff1a;【Unity ShaderGraph】| Shader Graph入门介绍 | 简介 | 配置环境 | 窗口介绍 | 简单案例下面就开始看一下具体的制作流…

多元高斯分布全解析

大纲 公式推导参数估计高斯分布运算高斯分布性质高斯过程&#xff08;Gaussian process&#xff09; 概念区分 边缘分布(marginal distribution)和联合分布概率密度函数和概率分布函数 1. 多元高斯分布公式推导 首先我们知道一元高斯分布是&#xff1a; N ( x ∣ u , σ 2…

2023年【北京市安全员-B证】考试试卷及北京市安全员-B证模拟考试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 北京市安全员-B证考试试卷考前必练&#xff01;安全生产模拟考试一点通每个月更新北京市安全员-B证模拟考试题题目及答案&#xff01;多做几遍&#xff0c;其实通过北京市安全员-B证在线考试很简单。 1、【多选题】《…

轻松合并Excel工作表:Java批量操作优化技巧

摘要&#xff1a;本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 在Excel中设计表单时&#xff0c;我们经常需要对收集的信息进行统计分析。例如&a…

web自动化测试——跨平台设备管理方案Selenium Grid

跨平台设备管理方案Selenium Grid 一、Selenium Grid简介二、使用场景场景一&#xff1a; 实现分布式执行测试&#xff0c;提高执行效率场景二&#xff1a; 解决浏览器兼容性问题新特性 三、Selenium Grid4原理分析四、环境安装五、运行方式&#xff1a;单机运行 - 独立模式1. …

SpringCloud之OpenFeign调用解读

目录 基本介绍 引进 OpenFeign概述 OpenFeign作用 FeignClient EnableFeignClients Java代码实战 实战架构 父工程pom文件 teacher-service服务 student-service服务 测试 自定义配置 基本介绍 引进 如果我们利用RestTemplate发起远程调用的代码时会存在一些…

docker部署nginx并设置挂载

前言&#xff1a; 最近在学习docker和nginx&#xff0c;因为容器在运行过程中&#xff0c;相关的配置文件及日志都会存在容器内。对容器以来较高&#xff0c;当容器不存在的时候。所有的文件也就都没有了。并且当需要查看日志&#xff0c;修改配置文件的时候必须进入到容器内部…