Asp.Net Core 过滤器之Filter

news/2025/12/4 2:35:05/文章来源:https://www.cnblogs.com/pengboke/p/19304577

过滤器(Filter)

1.概念

过滤器(Filter)是 ASP.NET Core MVC 的一种 拦截器机制,可以在 Controller 或 Action 执行前后插入逻辑。
它类似中间件,但只作用于 MVC/Web API 请求(控制器和操作方法),不能拦截静态文件或 Minimal API。

通俗理解:中间件作用于整个请求管道,过滤器作用于“控制器动作”,是请求的局部“钩子”。

特点:

  • 只作用于 MVC / API Controller(或者 Razor Pages)
  • 可以处理横切关注点:认证、授权、日志、异常处理、缓存等
  • 与中间件类似,但作用范围更细(仅限 MVC 请求)

2.权限过滤器(Authorization Filter)

2.1概念

职责 / 时机

  • 最先运行(在认证之后),用于授权判断(是否有权限访问)。
  • 可短路:如果未通过授权,可直接设置 context.Result 返回 401/403,后续 Filter/Action 不会执行。

接口

  • 同步:IAuthorizationFilterOnAuthorization
  • 异步:IAsyncAuthorizationFilterOnAuthorizationAsync) —— 推荐使用异步实现。

典型场景

  • 检查用户是否认证/是否有角色/是否有某个 Claim。
  • 实现自定义 [RequireRoles]、API Key 校验(需先认证)等。

2.2示例

2.2.1配置认证授权

注册认证服务,并指定默认认证方案为 "Bearer"。AddJwtBearer里的配置我们之前在注册认证(AuthenticationExtensions)的时候也了解过:发行者(Issuer)、接受者(Audience),剩下的就是token相关配置:过期、验证签名、签名密钥。那个是微服务有认证中心,这个是单体服务。

注册授权服务(配合 [Authorize]、角色验证等使用)

image-20251117175643236

启用认证/授权中间件

image-20251117180257374

2.2.2配置Scalar支持BearerAuth认证

自定义BearerSecuritySchemeTransformer添加BearerAuth认证方式

image-20251117001340204

注册OpenApi,让后在OpenApi中注入Bearer认证方案

image-20251117001418152

在开发环境中启用 Scalar UI(位于 /scalar/v1),禁用外部字体并把根路径 / 自动重定向到 Scalar 文档页面。

image-20251117001523007

launchSettings.json中配置 "launchBrowser": true,启动项目自动打开浏览器

启动项目,ScalarAuthentication就有了BearerAuth认证方案了

image-20251117002746975

2.2.3生成Token

从配置读取密钥、发行者(Issuer)和受众(Audience),用用户ID与角色生成相应的声明,再使用HMAC-SHA256 对称加密算法签名,最终创建并返回一个有效期 1 小时的 JWT。

image-20251117003043014

创建2个api

  • Login:模拟登录获取token
  • Admin:模拟只有Admin用户才能访问

image-20251117174933464

使用Scalar获取token

image-20251117175101274

2.2.4自定义权限过滤器(RequireRolesAttribute)

RequireRolesAttribute 是一个可加在控制器或方法上的自定义授权特性,它通过实现 IAuthorizationFilter 在执行动作前验证用户是否已认证并包含指定角色,若无权限则返回 401 或 403 直接终止请求。

image-20251117175236705

使用的时候在方法上加上特性(RequireRoles)和角色(Admin)

image-20251117175357929

2.2.5测试

/api/User/login接口设置参数userIdrole(区分大小写),发送请求获取token

image-20251117180801895

在首页设置token,这样每次请求都会带上

image-20251117181008999

请求api/User/admin授权通过即可

image-20251117181108499

创建一个超级管理员的接口[RequireRoles("SuperAdmin")]

image-20251117181607628

启动项目,不设置token,接口返回401,未认证

{"type": "https://tools.ietf.org/html/rfc9110#section-15.5.2","title": "Unauthorized","status": 401,"traceId": "00-96c74738e8cb1d4cbbd081d106e92fdc-beaeda2ae4e6b0d9-00"
}

image-20251117181725980

如果还是角色还是admin,然后获取token后请求,那返回403,未授权

{"type": "https://httpstatuses.io/403","title": "Forbidden","status": 403,"traceId": "00-bcfb934c9ae3779654656e9f5ed64b62-1cb30ea7ea0ec0ea-00"
}

image-20251117181834155

重新获取SuperAdmintoken

image-20251117182034020

再次请求才是200,授权通过

{"message": "SuperAdmin 授权通过","userId": "1","role": "SuperAdmin"
}

image-20251117182121290

2.3异步接口(IAsyncAuthorizationFilter)

同步接口 (IAuthorizationFilter)

  • 执行时阻塞线程,直到方法执行完成
  • 如果方法内有耗时 I/O(如数据库查询),线程会被占用
  • 框架会自动把同步过滤器也包装到异步请求管道中,但本身还是阻塞

异步接口 (IAsyncAuthorizationFilter)

  • 支持异步 I/O,执行过程中可以释放线程等待结果
  • 对高并发、耗时操作非常友好
  • 框架直接等待 Task 完成,非阻塞执行
接口 优点 缺点 适用场景
IAuthorizationFilter 简单、轻量、CPU-bound 快 阻塞线程,不适合异步 I/O 只检查 Claims、角色或内存数据
IAsyncAuthorizationFilter 可异步、释放线程、适合高并发 I/O 代码稍复杂,需要 async/await 数据库/缓存/远程服务授权验证

因为我们的例子没有数据库、缓存等异步操作,所以我们的例子使用的是同步;如果存在数据库、Redis可以使用异步接口(IAsyncAuthorizationFilter)进行优化

IAsyncAuthorizationFilter示例

比如说我们用户的角色需要去数据库查询,这时候就可以使用异步接口(IAsyncAuthorizationFilter)优化

image-20251117195627163

3.资源过滤器(Resource Filter)

3.1概念

Resource Filter 是 ASP.NET Core 五种过滤器之一,位于 Action 执行前后,可以处理请求和响应,是资源级别的过滤器。

接口

  • OnResourceExecuting:Action 执行前,可短路请求(比如缓存命中、权限不足)
  • OnResourceExecuted:Action 执行后,可处理结果(比如写缓存、记录日志)

特点

  • 最早执行的过滤器之一,最晚离开
  • 可以决定是否执行 Action
  • 可以在执行前获取请求上下文,执行后处理结果
  • 支持同步(IResourceFilter)和异步(IAsyncResourceFilter)实现

典型应用场景

  • 缓存:GET 请求结果缓存,减少重复执行 Action
  • 日志:记录请求和响应信息、耗时统计
  • 权限控制:基于用户角色或资源权限判断访问
  • 资源初始化/释放:数据库连接、外部 API 初始化等

资源过滤器是 Action 执行前后操作的入口,可以短路请求或处理结果,是缓存、权限和日志等资源级操作的理想位置。

3.2示例

3.2.1自定义资源过滤器(ResponseCacheFilter)

创建ResponseCacheFilter,继承并实现IResourceFilter

依赖注入内存缓存(IMemoryCache)和自定义缓存选项

image-20251117203638353

CacheOptions缓存配置项:

  • DurationSeconds:绝对过期时间
  • SlidingExpirationSeconds:滑动过期时间

image-20251117203859306

OnResourceExecuting在进入Action之前执行:

  • 如果不是Get请求,直接返回,只缓存查询接口的结果
  • 生成缓存key(URL + 参数 + SHA256)
  • 根据key查询缓存,如果缓存命中,直接设置context.Result

在 ASP.NET Core 的资源过滤器中,只要在 OnResourceExecuting 设置 context.Result,框架就会短路执行管道,直接返回结果,不执行 Action。

image-20251117204233260

OnResourceExecuted 在 Action 执行后触发:

  • 只缓存 GET 请求
  • 只支持接口返回类型为ContentResultJsonResultObjectResult
  • 生成缓存Key(URL + 参数 + SHA256)
  • 将接口的返回结果写入缓存,缓存策略:绝对过期 + 滑动过期

为什么只支持接口返回类型为ContentResultJsonResultObjectResult

缓存需要明确知道如何获取响应内容

类型 缓存内容获取方式 说明
ContentResult contentResult.Content 已经是字符串,可以直接缓存
JsonResult JsonSerializer.Serialize(jsonResult.Value) 对象需要序列化成 JSON 字符串才能缓存
ObjectResult JsonSerializer.Serialize(objectResult.Value) 通用对象返回,也需要序列化成字符串

如果是其它返回类型(比如 FileResultRedirectResultStatusCodeResult 等),它们的内容不是简单字符串或对象,缓存起来比较复杂。所以示例中只处理了最常用的三种类型,确保缓存逻辑简单可靠。

缓存策略:绝对过期 + 滑动过期?

类型 含义 示例
绝对过期(Absolute Expiration) 缓存项在固定时间后一定过期,不管是否访问 设置 60 秒,缓存 60 秒后自动失效
滑动过期(Sliding Expiration) 缓存项如果在指定时间内被访问,会延长过期时间 设置 30 秒,如果每 10 秒访问一次,缓存会延长 30 秒到下一次访问

两者可以组合使用:

  • 绝对过期 防止缓存无限存在
  • 滑动过期 保证热点数据被频繁访问时不会过早失效

总结

  • 滑动过期延长的时间不会超过绝对过期时间
  • 缓存必须在滑动过期时间内访问才能延长,否则就会因为滑动过期而过期
  • 到达绝对过期时,缓存无条件失效

在绝对过期时间内,每次访问会延长缓存到“滑动过期时间”,但不会超过绝对过期;一旦到达绝对过期,缓存无条件失效。

image-20251117204724993

缓存key组成:

  • URL
  • 参数
  • sha256算法
/Product/list|keyword=9|page=2|pageSize=5

image-20251117210824078

分页参数必须通过 URL 查询字符串传入,默认值好像没有生效,request.Query获取不到pagepageSize,暂时也没有影响,但是留意下

image-20251117211116615

3.2.2注册资源过滤器、缓存、配置

自定义过滤器 ResponseCacheFilter 依赖本地缓存 IMemoryCache 和配置选项 CacheOptions,三者均需通过依赖注入注册到容器中。

image-20251117211457683

3.2.3创建测试接口

ProductController

  • ProductController添加[ServiceFilter(typeof(ResponseCacheFilter))]

  • 模拟商品数据Products

  • GetListAsync:获取商品列表

image-20251117211844476

3.2.4测试

启动项目,打开Scalar,第一次请求/Product/list/Product/list会被写入缓存

image-20251117214101184

第二次请求/Product/list,会直接读取缓存

image-20251117214138824

过一分钟请求/Product/list,缓存过期,会重新写入缓存

image-20251117214256402

如果请求参数不一致,也会重新写入缓存

image-20251117214404358

3.3异步接口(IAsyncResourceFilter)

Resource Filter也有异步接口,如果需要数据库/缓存/远程服务授权验证,也可以使用异步接口

我这里也实现了一个异步接口的示例,支持分布式缓存,其他基本都一致

image-20251117214525474

使用前注册,然后配置在Controller上,我这里已经测试过,就不详细看了

俩个接口基本的都差不多,同步简单、快速,异步支持高并发,正常开发环境可能异步多一些,但用法都差不多

image-20251117214738688

4.动作过滤器(Action Filter)

4.1概念

动作过滤器(Action Filter)*是 ASP.NET Core MVC 的一种*管道机制,用于在 Controller 的 Action 方法执行前或执行后插入自定义逻辑。

  • 执行顺序:Authorization → Resource → Action → Exception → Result
  • 动作过滤器位于 Action 阶段,专门拦截 Action 方法的执行
  • 可以操作:
    • 请求参数(ActionExecutingContext)
    • Action 执行结果(ActionExecutedContext)

作用

  • 日志记录(请求参数、执行耗时、响应结果)
  • 权限检查(虽然也可以用 Authorization Filter,但部分自定义逻辑在 Action Filter 也可实现)
  • 数据验证或修改
  • 性能监控
  • 缓存(比如缓存 Action 执行结果)

同步接口
OnActionExecuting

  • 在 Action 方法调用前触发
  • 可以修改参数、取消执行(通过 context.Result = ...

OnActionExecuted

  • Action 方法执行完成后触发
  • 可以访问返回结果(Result)并修改或处理
public interface IActionFilter
{void OnActionExecuting(ActionExecutingContext context); // Action 执行前void OnActionExecuted(ActionExecutedContext context);   // Action 执行后
}

异步接口

参数说明

  • ActionExecutingContext context:Action 执行前的上下文
  • ActionExecutionDelegate next:执行 Action 的委托,返回 ActionExecutedContext

优点

  • 支持 await 异步操作
  • 避免阻塞线程,性能更好
public interface IAsyncActionFilter
{Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next);
}

生命周期

ControllerActionInvoker
│
├─ AuthorizationFilter
├─ ResourceFilter
├─ ActionFilter
│    ├─ OnActionExecuting
│    └─ Action方法执行
│    └─ OnActionExecuted
├─ ExceptionFilter
├─ ResultFilter
└─ 返回客户端

4.2示例

4.2.1自定义日志过滤器(ActionLoggingAsyncFilter)

这次我们使用异步接口IAsyncActionFilter

  • 继承IAsyncActionFilter,实现OnActionExecutionAsync
  • await next()前记录日志(请求参数)、开启计时,await next()就是执行Action

image-20251117221534474

await next()之后记录日志(响应结果)、结束计时,如果是异常则记录异常

同时是支持ObjectResultJsonResultContentResult三种返回类型

image-20251117221714845

这次使用全局注册,不用每个Controller单独使用特性,所有Controller都生效

image-20251117223114164

4.2.2测试

请求/Product/list

  • 第一次请求会记录请求参数和耗时、响应结果
  • 然后写入缓存
  • 第二次请求会直接读取缓存(缓存未过期)

因为资源过滤器(缓存)在动作过滤器之前执行,如果有缓存会直接返回,不会往下执行

image-20251117221932770

4.3同步接口(ActionLoggingFilter)

业务逻辑都一样,OnActionExecuting用于记录请求参数和开始计时

然后使用了context.HttpContext.Items存了Action开始执行时间

HttpContext.Items

HttpContext.Items 是一个 IDictionary<object, object> 类型的集合,用于在同一次 HTTP 请求的生命周期内存储临时数据。

特点:

  • 1.生命周期短:只在当前请求期间有效,请求结束后自动释放。
  • 2.类型不限:Key 可以是任意对象(常用 string 或 Type),Value 可以是任意对象。
  • 3.线程安全:单个请求通常是一个线程处理,所以不需要额外同步。

作用:实现请求级别的数据传递,避免使用全局静态变量或依赖注入传递数据。

image-20251117222459789

OnActionExecuted用于记录耗时、响应结果

image-20251117222851984

然后全局注册,剩下的就自己测试了

image-20251117223312541

5.异常过滤器(Exception Filter)

5.1概念

异常过滤器(Exception Filter) 是 ASP.NET Core MVC 中用于 捕获 Action 执行期间未处理异常 的组件,属于 过滤器管道的最后一层保护机制
它的目标是让系统在出现异常时:

  • 不崩溃
  • 不把内部错误曝露给客户端
  • 统一返回格式一致的错误响应
  • 记录日志或上报监控平台

异常过滤器只在 Action 执行阶段 捕获异常,不处理 Model 绑定阶段的异常(接口参数绑定的异常:FromBodyFromQueryFromHeader...)。异常过滤器 = Action 执行中所有未捕获异常的兜底处理器。

执行顺序如下: Action 执行 → 如果抛异常 → 异常过滤器捕获 → 返回统一 JSON → 停止异常继续冒泡

同步接口(IExceptionFilter)

OnException

  • 在 Action 执行或过滤器执行过程中 发生异常时触发
  • 可以记录日志
  • 可以统一包装异常为 JSON
  • 可以通过 context.Result = ... 返回自定义响应
  • 设置 context.ExceptionHandled = true 阻止异常继续抛出
public interface IExceptionFilter
{void OnException(ExceptionContext context); // 有异常时触发(同步)
}

异步接口(IAsyncExceptionFilter)

参数说明

  • ExceptionContext context:包含异常、HttpContext、Action 信息
  • Task:异步执行,可 await 调用日志服务、数据库、远程接口等

优点

  • 支持异步日志处理
  • 不阻塞线程
  • 性能更优,推荐现代项目使用
public interface IAsyncExceptionFilter
{Task OnExceptionAsync(ExceptionContext context); // 有异常时触发(异步)
}

异常过滤器是 ASP.NET Core MVC 中用于捕获 Action 执行期间异常的机制,提供统一错误响应、区分业务异常与系统异常、记录日志并防止异常向外冒泡,是 MVC 控制器层的专属“异常统一入口”。

5.2示例

5.2.1自定义全局异常过滤器(GlobalExceptionFilter)

自定义业务异常(BusinessException),用于区分系统异常和业务异常

image-20251118001703066

GlobalExceptionFilter继承IExceptionFilter实现OnException(ExceptionContext context)方法

image-20251118001549262

OnException

  • 1.获取请求路径和方法

  • 2.如果是业务异常:记录状态码和错误消息

  • 3.如果是系统异常:记录状态码和错误消息之后如果是生产环境也显示堆栈消息

为什么区分业务异常和系统异常?

区分业务异常系统异常的主要原因是为了处理策略不同

  • 业务异常(BusinessException)
    • 代表可预期的、与业务逻辑相关的错误,比如用户输入错误、库存不足、余额不足等。
    • 处理方式:向前端返回明确的错误信息(友好提示),通常不需要记录堆栈,也不触发告警。
  • 系统异常(SystemException / 未捕获异常)
    • 代表不可预期的、底层系统或框架错误,如数据库连接失败、空引用、文件读取失败等。
    • 处理方式:记录详细日志、堆栈信息,可能需要告警、排查问题,前端返回通用错误信息,避免泄露内部实现。

一句话总结:区分业务异常和系统异常,可以实现对用户友好提示、降低系统风险,并便于开发排查问题

image-20251118001809521

  • 4.最后统一返回JsonResult

image-20251118002226470

5.2.2全局注册GlobalExceptionFilter

所有Controller都生效

image-20251118002722246

注:我们之前使用ProblemDetails中间件,会统一返回异常格式,如果我们捕获到异常,然后自定义格式,这个就不生效了

image-20251118002812258

5.2.3构建异常测试接口

创建2个接口:

  • GetError:返回系统异常
  • GetBusinessError:返回业务异常

image-20251118003001713

5.2.4测试

请求/Product/error,返回500,代表服务器错误

image-20251118003109368

请求/Product/businesserror,返回400,代表业务错误

image-20251118003150212

5.3异步接口(IAsyncExceptionFilter)

GlobalExceptionAsyncFilter和同步实现上没有什么区别,也是在OnExceptionAsync中实现,区分业务异常和系统异常

image-20251118003531868

判断完业务异常和系统异常之后,构建统一的JsonResult

因为是异步方法,最后需要返回Task.CompletedTask

image-20251118003623324

注册到容器

image-20251118004435050

6结果过滤器(Result Filter)

6.1概念

结果过滤器用于在 Action 方法执行完成并准备产生响应(IActionResult 前后运行逻辑。它能:

  • 在结果执行前(OnResultExecuting)拦截并修改/替换 IActionResult(可短路,直接返回自定义结果)。
  • 在结果执行后(OnResultExecuted)读取执行结果、记录日志或修改响应流(若要修改响应内容通常需替换/捕获 HttpContext.Response.Body)。

它适合做:响应缓存、统一包装(如统一 JSON 结构)、记录响应体、设置响应头、压缩、内容审计等。

ASP.NET Core 的过滤器管线顺序大致为(从前到后):

  • 1.Authorization filters
  • 2.Resource filters
  • 3.Action filters
  • 4.Exception filters
  • 5.Result filters ← 这里
  • 6.中间件环绕整个请求(Use...)

Result Filter 的两个时点:

  • 执行前OnResultExecuting(ResultExecutingContext) / 在异步中是 ResultExecutingContext 在调用 await next() 之前。 是 在 action 已产生 IActionResult 之后、写出之前 被调用的 —— 所以可以合法地读取并替换 context.Result,这就是 Result Filter 用来包装/短路/修改响应的正确位置。
  • 执行后OnResultExecuted(ResultExecutedContext) / 在异步中 ResultExecutedContextawait next() 之后由返回值提供。是 写出之后的通知,只能读或记录,不能再改变 context.Result(只读属性)。

常用接口:

  • IResultFilter:同步,方法 OnResultExecuting(ResultExecutingContext)OnResultExecuted(ResultExecutedContext)
  • IAsyncResultFilter:异步,方法 Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)

6.2示例

6.2.1自定义结果过滤器(IResultFilter)

GlobalResultFilter继承IResultFilter,并实现OnResultExecuting(ResultExecutingContext context)方法

SensitiveFields:存储需要脱敏的字段

JsonOptions:统一Json配置,防止每次创建,提升性能

image-20251118193324048

HttpContext存储Stopwatch记录接口耗时

只处理ObjectResultJsonResultContentResult三种返回结果,并获取响应数据

image-20251118193514855

如果有返回数据:

  • 如果是JSON文本(JsonResultContentResult):

    • json格式: JsonNode.Parse转换为JsonNode
    • 普通文本:JsonValue.Create转换为JsonNode
  • 如果是对象(ObjectResult):先序列化为 JSON,再解析为JsonNode

  • 解析完JsonNode,调用MaskJsonNode递归脱敏

  • 如果异常记录日志和返回null

image-20251118193724578

统一构建response

  • success:根据 statusCode 决定 success

  • data:脱敏后的数据

  • message:根据 statusCode 决定 message

  • traceId:ASP.NET Core 自动为 每个 HTTP 请求分配的全局唯一 ID(GUID 样式的字符串)

  • 最后统一设置context.Result

image-20251118194457332

响应结果写出之后记录日志并记录耗时

image-20251118195020757

6.2.1构建测试接口

这俩个接口都是模拟用户的数据,存在敏感字段

image-20251118195150550

启动项目,打开Scalar,请求/api/User/list,日志正常记录,响应数据也进行了脱敏

image-20251118195427253

6.3异步接口(IAsyncResultFilter)

异步接口(IAsyncResultFilter)只有一个方法OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)

image-20251118200252162

这部分代码跟同步接口一样:

  • 处理ObjectResultJsonResultContentResult三种结果响应数据
  • 记录耗时
  • 脱敏
  • 构建统一响应数据
  • 设置context.Result后直接返回前端数据了

在调用 await next() 之前:Action 已经执行并产生 IActionResult,但响应尚未写入客户端,此时可以修改或替换 context.Result。
在调用 await next() 之后:响应已经写入客户端,此时只能做日志、清理或监控,无法再修改 context.Result。

image-20251118200404196

响应写入客户端后,日志记录响应数据和耗时

image-20251118200949291

7.总结

7.1五种过滤器

ASP.NET Core 过滤器分为 五类(按执行顺序):

类型 接口 异步接口 执行时机 作用 / 用途
权限过滤器 (Authorization Filter) IAuthorizationFilter IAsyncAuthorizationFilter Action 执行前 校验用户是否有权限访问,例如 [Authorize]。可短路请求(不执行 Action)。
资源过滤器 (Resource Filter) IResourceFilter IAsyncResourceFilter Action 执行前/后 可用于缓存、全局请求前处理或短路请求。OnResourceExecuting/Executed 包围 Action + Result 执行。
动作过滤器 (Action Filter) IActionFilter IAsyncActionFilter Action 执行前/后 对 Action 方法入参、返回结果进行处理或包装。可短路 Action 执行(OnActionExecuting)。
异常过滤器 (Exception Filter) IExceptionFilter IAsyncExceptionFilter Action 或结果执行异常时 捕获异常,可返回自定义结果或日志处理,不适合处理管道中间件异常。
结果过滤器 (Result Filter) IResultFilter IAsyncResultFilter Action 执行完成、结果写出前/后 对 Action 返回的结果进行统一包装、脱敏、日志记录、缓存等处理。OnResultExecuting 可修改结果,OnResultExecuted 仅能记录。

7.2同步/异步接口

权限过滤器

  • 同步接口 (IAuthorizationFilter)
    • void OnAuthorization(AuthorizationFilterContext context):同步执行授权逻辑,可短路请求。
  • 异步接口 (IAsyncAuthorizationFilter)
    • Task OnAuthorizationAsync(AuthorizationFilterContext context):异步执行授权逻辑,可访问数据库/缓存。

资源过滤器

  • 同步接口 (IResourceFilter)
    • void OnResourceExecuting(ResourceExecutingContext context):Action 执行前,可短路请求。
    • void OnResourceExecuted(ResourceExecutedContext context):Action 和 Result 执行后,可做日志或清理。
  • 异步接口 (IAsyncResourceFilter)
    • Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next):可在 await next() 前后分别执行逻辑,前:Action + Result 未执行,后:已执行完。

动作过滤器

  • 同步接口 (IActionFilter)
    • void OnActionExecuting(ActionExecutingContext context):Action 执行前,可修改参数或短路请求。
    • void OnActionExecuted(ActionExecutedContext context):Action 执行后,可修改返回值或做日志。
  • 异步接口 (IAsyncActionFilter)
    • Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next):可在 await next() 前后分别处理逻辑。

异常过滤器

  • 同步接口 (IExceptionFilter)
    • void OnException(ExceptionContext context):捕获 Action 或 Result 异常,可返回自定义结果。
  • 异步接口 (IAsyncExceptionFilter)
    • Task OnExceptionAsync(ExceptionContext context):异步捕获异常,可做日志或调用服务。

结果过滤器

  • 同步接口 (IResultFilter)
    • void OnResultExecuting(ResultExecutingContext context):Action 执行后、结果写回前,可修改结果。
    • void OnResultExecuted(ResultExecutedContext context):结果写回后,只能做日志或监控。
  • 异步接口 (IAsyncResultFilter)
    • Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next):可在 await next() 前修改结果,后记录日志。

7.3同步vs异步

同步接口(IAuthorizationFilterIResourceFilterIActionFilterIExceptionFilterIResultFilter

使用场景

  • 过滤器内部逻辑非常简单,不需要访问数据库、缓存、远程服务或执行耗时 I/O。
  • 执行非常快,可以直接在同步线程完成。
  • 适合:参数验证、简单权限判断、日志记录、数据脱敏(在内存操作)。

优点

  • 实现简单,调用链直接,不需要 async/await
  • 对性能要求高、I/O 不密集的情况更高效。

异步接口(IAsyncAuthorizationFilterIAsyncResourceFilterIAsyncActionFilterIAsyncExceptionFilterIAsyncResultFilter

使用场景

  • 需要访问数据库、缓存、Web API 或其他异步 I/O 操作。
  • 过滤器逻辑可能耗时,需要避免阻塞线程池。
  • 适合:异步权限验证(JWT、数据库角色检查)、缓存读取、异步日志写入、异步统计上报。

优点

  • 避免阻塞 ASP.NET Core 线程,提高吞吐量。
  • 可以在 await next() 前后处理逻辑,实现前后环绕操作。

简单规则

  • 不做异步 I/O → 用同步接口

  • 需要异步 I/O → 用异步接口

  • 异步接口可以兼容同步逻辑(直接返回 Task.CompletedTask)。框架优先调用异步接口,同步接口被忽略。

📌 创作不易,感谢支持!

每一篇内容都凝聚了心血与热情,如果我的内容对您有帮助,欢迎请我喝杯咖啡☕,您的支持是我持续分享的最大动力!

💬 加入交流群(QQ群):576434538

微信打赏

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

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

相关文章

Asp.Net Core 请求管道中间件之Middleware

前言 中间件(Middleware) 概念 中间件是 ASP.NET Core 请求处理管道(pipeline) 中的一段可插拔组件,接收 HttpContext、执行任意逻辑、并决定是否把请求交给管道中的下一个中间件。管道呈“洋葱模型”(请求顺序进入…

Git推送从失败到成功的解决方案

问题描述 今天在尝试将本地代码推送到GitHub远程仓库时,遇到了推送失败的问题。使用git push命令后,出现了以下错误: fatal: unable to access https://github.com/guchen66/IT.Tangdao.Core.git/: OpenSSL SSL_rea…

Microsoft-Store-error

Microsoft-Store-error导航 (返回顶部)1. Store初始化失败1.1 为何要卸载Edge 1.2 如何卸载Edge 1.3 为何删除Edge会影响微软商店2. 微软商店无法联网2.1 解除网络隔离的办法有:3. CheckNetIsolation解除网络隔离3.1 查…

STM32 HAL库 硬件IIC 从机一些问题整理(转载)

一、从机双地址,在回调函数中获取主机访问的地址:void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle) {uint16_t slaveaddrcode = I2C_GET_ADDR_MATCH(I2cHandle);printf("R:%d\r\n",sl…

本地人推荐的火锅,天台火锅/麻辣火锅/老火锅/市井火锅/川渝火锅约会地点推荐榜单

专业视角下的川渝火锅团建选址指南 随着企业团建需求的多元化发展,川渝火锅凭借其独特的社交属性与浓郁的文化氛围,已成为企业团建活动的优选场所。本文基于市场调研数据与消费者反馈,从空间容量、服务质量、特色体…

OBDSTAR P003+ Kit for DC706 Tablets: Simplify ECU, EEPROM, Flash IMMO Data Diagnostics Programming

Troubleshooting ECU & IMMO Challenges on European/American Cars? Meet the OBDSTAR P003+ Kit The Pain Point: Decrypting ECU & IMMO Data on European/American Vehicles For European and American m…

全程复盘:一次枚举值永远 Cloud2的坑——从玄学随机到只读属性

问题描述 在 .NET 6 + WPF 程序中,使用 TangdaoDataFaker<MusicInfo>.Build(200000) 生成测试数据时,控制台 20 条并行日志显示 QQ / Cloud / Kugou 随机分布,但 DataGrid 界面整屏只显示 Cloud2。同一套代码…

M726芯片

根据您提供的《M726 数据手册》,我为您整理了该芯片的关键性能参数,并列出了性能相近的竞品型号及价格参考(基于公开市场信息,实际价格以供应商报价为准):M726 芯片核心性能摘要 类别 参数内核 ARM Cortex-M0,最…

Fast Easy Electric Oil Siphon Pump: Professional Fluid Transfer for Cars, Motorcycles Boats

The Hidden Challenges of Fluid Transfer: Why Mechanics and Car Owners Need a Better Solution Anyone who’s ever drained engine oil, changed coolant, or refilled a motorcycle’s fuel tank knows the frus…

AutoCloseable接口 try-with-resources 、 try-catch-finally

在学习过程中发现了这样一段注释/*** 实现了 AutoCloseable 接⼝的类,在 try() ⾥声明该类实例的时候,在 try 结束后⾃动调⽤的 close ⽅法,这个动作会早于* finally ⾥调⽤的⽅法,不管是否出现异常,try() ⾥的实…

第44天(中等题 数据结构)

打卡第四十四天 2道中等题题目:思路:以每个点为中心,统计与它距离相同的点对数量 代码: class Solution { public:int numberOfBoomerangs(vector<vector<int>>& points) {int ans = 0;int n = po…

rizhi

rizhicat /tmp/ray/session_latest/logs/dashboard_agent.log

element-plus el-select

<template><div class="app"><h4>=========默认情况下的select组件在设置collapse-tags-tooltip后,只有在鼠标移入折叠标签后才显示文本</h4><el-selectmultiplecollapse-tagsc…

centos6.9编译安装python37——SSL 模块缺失、GCOV 链接错误,以及 Bash 命令缓存混乱

安装参考这篇 https://www.cnblogs.com/opsprobe/p/11266939.html 🚀 Python 编译与环境部署深度指南:告别 SSL 缺失和 Bash 缓存困扰 📝 导言 在 Linux 系统上从源码编译安装 Python,尤其是在企业级环境(如 Ce…

在 Windows 上本地部署 ComfyUI + zImage Turbo 模型(低显存友好)

原文:https://www.cnblogs.com/zwj/p/19304354/ai_local_zimg我是觉得我原文写的可能比较乱,于是让AI整理了一下我的原文,下方内容就是QwenMax根据我原文的内容生成的,仅供参考。 在 Windows 上本地部署 ComfyUI +…

sg.取消按钮焦点框

在PySimpleGUI中,按钮上的虚框通常是由焦点指示器(focus indicator)引起的。要取消这个虚框,可以通过以下两种方法实现: 方法1:禁用按钮的焦点属性 在按钮参数中添加 focus=False,直接禁用焦点效果: import Py…

代码随想录Day27_贪心1

代码随想录Day27_贪心1分发饼干 代码 class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int index = s.s…

Day10-20251203

本文介绍了Java中变量、常量及其命名规范。主要内容包括:1)变量的定义与声明语法,强调Java是强类型语言;2)变量的三种作用域(类变量、实例变量、局部变量)及示例代码;3)常量的定义方式(使用final关键字)和命…

面向人机文明的价值协同:理论、实践与评估的完整框架

面向人机文明的价值协同:理论、实践与评估的完整框架 摘要:本文系统性地整合了关于“AI元人文构想”的完整论述,旨在应对人工智能自主性增强所带来的根本性挑战:如何与AI建立可验证、可进化、可信任的价值协同关系…

251203 完成比完美重要

今天运气可以,遇到了直拍侠,直接买了我的自行车。没有多一句话,就成功成交了。开心,希望后面继续 做完纠结了半天,还是决定换一个手机,换了华为荣耀500pro,长得还挺好看的,明天就能拿到了。还是不用苹果了。 准…