Filter过滤器
ASP.Net Core中,Filter(过滤器)实现了一种简化的AOP面向切面编程机制,它能在请求被控制器处理的前后统一执行自定义逻辑,从而实现诸如日志记录、权限检查、错误处理等功能。
Filter和Middleware的区别
Filter(过滤器)和Middleware(中间件)都是ASP.Net Core中用于拦截请求被控制器处理的机制,但它们的执行时机和作用范围有所不同。
执行时机:中间件是在HTTP请求管道中按顺序执行的组件,在处理请求时中间件首先被执行,响应回传给客户端时,执行顺序会反向进行,而过滤器则是在具体控制器和操作方法执行之前或之后运行的,从全局来看,在HTTP请求的处理管道中,中间件位于过滤器的“外层”。
作用范围:中间件是作用于整个应用的HTTP处理管道上的,它通常用于执行全局性的业务逻辑,过滤器则是特定于控制器或控制器方法的。认证和授权就是一个说明这种差异的例子,认证是全局性的,特别适合使用中间件实现,而授权的业务逻辑对不同的功能来说可能是差异化的,它就适合使用过滤器实现。
总而言之,过滤器和中间件功能存在重合,它们能实现同样的需求,但我们习惯于将全局性的业务逻辑写入中间件,而针对特定一组控制器的切面逻辑则更倾向于使用过滤器封装。
几种内置Filter类型
ASP.Net Core内置了5种Filter类型:
- AuthorizationFilter:用于处理授权逻辑,检查请求是否合法,通常第一个执行
- ResourceFilter:用户处理缓存和模型绑定等逻辑
- ActionFilter:所谓的Action其实就是控制器方法,ActionFilter会在控制器方法执行之前和之后执行
- ExceptionFilter:用于处理异常
- ResultFilter:控制器方法执行完成后会执行ResultFilter,其中可以插入特定逻辑统一处理返回结果
我们可以基于这些内置Filter类型编写自定义过滤器。
自定义ActionFilter
自定义ActionFilter可以实现IActionFilter或IAsyncActionFilter接口,前者是同步方式写法而后者是异步方式写法,这里我们采用异步实现编写一个例子。
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc.Filters;
namespace DemoWebAPI.Filters;
public class MyActionFilter : Attribute, IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
Console.WriteLine($"收到请求 {context.HttpContext.Request.GetDisplayUrl()}");
await next();
Console.WriteLine("请求处理完成");
}
}
代码中,我们的过滤器实现了IAsyncActionFilter接口,它拦截了控制器方法的执行逻辑,在控制器方法执行前后输出了一些信息。此外,MyActionFilter同时还是一个注解,能够标注到控制器类或控制器方法上。
下面例子控制器中,我们将自定义的过滤器注解标注在了控制器类上,这样控制器内的所有控制器方法执行前后都会执行过滤器逻辑。
using DemoWebAPI.Filters;
using DemoWebAPI.Model;
using Microsoft.AspNetCore.Mvc;
namespace DemoWebAPI.Controllers;
[ApiController]
[Route("api/[controller]")]
[MyActionFilter]
public class DemoController : ControllerBase
{
[HttpGet("[action]")]
public ActionResult<ApiResult> Hello()
{
return ApiResult.Success();
}
}
此外,我们也可以将过滤器注解标注在控制器方法上,这样只有标注注解的方法才会执行过滤器逻辑。
[HttpGet("[action]")]
[MyActionFilter]
public ActionResult<ApiResult> Hello()
{
// ...
}
有关其它Filter类型
除了泛用性最强的ActionFilter,其余几种Filter类型都有其特定的使用场景,我们将在后续章节涉及相关功能时详细介绍。