筛选器 Filter
筛选器 Filter
五种筛选器
- Authorization Filter:用于验证Request合不合法,不合法后面就直接跳过,权限角色认证、登陆授权
- Resource Filter:用于对 Model 加工处理,资源缓存、防盗链
- Exception Filter:当系统中出现未经处理的异常的时候,异常筛选器就会执行,异常日志收集
- Action Filter:最常使用的Filter,封包进出都会经过它,操作日志、参数验证,权限控制
- Result Filter:当Action完成后,可以对结果进行格式化、大小写转换
三种注册方式
Action 注册方式 :为单个 Action 方法局部注册
[AuthonizationFilter()] public IActionResult Index() {/* code */}
Controller 注册方式 :为 Controller 所有 Action 注册
[AuthonizationFilter()] public class FirstController : Controller{}
全局注册方式 :WebApplicationBuilder 服务中注册
builder.Services.Configure<MvcOptions>(options => { options.Filters.Add<MyExceptionFilter>(); options.Filters.Add<MyActionFilter>(); });
使用特性的 Filter 需要继承对应的
FilterAttribute
借助
TypeFilter
和ServiceFilter
进行局部注册ServiceFilter
和TypeFilter
都实现了IFilterFactory
,用于创建 FilterTypeFilter
每次都会创建一个新的实例,不需要将自定义 Filter 注册到服务[TypeFilter(typeof(MyExceptionFilter))]
ServiceFilter
生产的 Filter 取决于在 services 中如何注册builder.Services.AddSingleton<MyExceptionFilter>(); // 注册 Filter 为单例 [ServiceFilter(typeof(MyExceptionFilter))] // 局部注册
取消和设置短路
- 通过设置提供给筛选器方法的 ResourceExecutingContext 参数上的 Result 属性,可以使筛选器管道短路。
- 当设置 Result 后,将阻止执行管道的其余阶段
Exception filter
实现 IExceptionFilter 或 IAsyncExceptionFilter
当系统中出现未处理异常的时候,我们需要统一给客户端返回如下格式的响应报文:
{“code”:”500”,”message”:”异常信息”}
对于开发环境中message是异常堆栈,对于其他环境message应该用general的报错信息。
非常适合捕获发生在操作中的异常,不如错误处理中间件灵活。
示例代码
public class MyExceptionFilter : IExceptionFilter { private readonly IHostEnvironment environment; public MyExceptionFilter(IHostEnvironment environment) { this.environment = environment; // 注入 IHostEnvironment,获取当前环境 } public void OnException(ExceptionContext context) { if(context.ExceptionHandled==false) { ObjectResult result = new(new { code = 500, message = environment.IsDevelopment() ? context.Exception.Message : "内部错误" }); result.StatusCode = 500; context.Result = result; context.ExceptionHandled = true; // 标记为已处理 } } }
Action Filter
实现 IActionFilter 或 IAsyncActionFilter 接口
在 Action 方法之前和之后执行
ActionExecutingContext 提供以下属性:
- ActionArguments - 用于读取操作方法的输入。
- Controller - 用于处理控制器实例。
- Result - 设置
Result
会使操作方法和后续操作筛选器的执行短路。
ActionExecutedContext 提供
Controller
和Result
以及以下属性:在操作方法中引发异常将阻止运行后续筛选器,与设置
Result
不同,结果被视为失败而不是成功。对于
IAsyncActionFilter
,还提供了 ActionExecutionDelegate 属性用于:- 执行所有后续操作筛选器和操作方法。
- 返回
ActionExecutedContext
。
public class SampleAsyncActionFilter : IAsyncActionFilter { public async Task OnActionExecutionAsync( ActionExecutingContext context, ActionExecutionDelegate next) { // Do something before the action executes. await next(); // Do something after the action executes. } }
若要对
IAsyncActionFilter
设置短路,需要为 ActionExecutingContext 分配Result
并且不调用next