Filter
是延续Asp.Net Mvc
的产物,同样保留了五种的Filter
,分别是Authorization Filter
、Resource Filter
、Action Filter
、Exception Filter
、Result Filter
。通过不同的Filter
可以有效处理一些共通的动作。
Filter Pipleline
中首先执行,并用于决定当前客户端 Request
请求权限的身份授权验证Authorization
后面执行,同时在后面的其它过滤器完成后还会执行;作用于Api
资源授权、缓存处理等一些可以性能原因的拦截,因为运行在模型绑定前,所以这里的操作都会影响模型绑定。Action
方法前后,用于 Action
审计日志、传递参数和方法返回值的处理。Action
结果之前执行,且执行 Action
成功后执行,使用逻辑一般围绕 Action
入参的验证和格式化返回值。在开始写代码前需引用nuget包或包含的集成包
Microsoft.AspNetCore.Mvc.Abstractions
均可;下面我用异步的方式,继承相应过滤器实现对应功能,说这么多,还是看代码吧!
权限过滤器,通过 Authorization Filter
可以实现复杂的 防篡改
、验证XsrfToken防伪令牌
等操作。具体代码如下:
///
/// SB过滤器 - 权限
///
public class SBAuthorizationFilterAttribute : Attribute, IAsyncAuthorizationFilter
{
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
// 参数防篡改
// 验证XsrfToken防伪令牌
// ..
}
}
资源过滤器,通过 Resource Filter
可以进行 Api资源授权
、 缓存处理
等复杂操作。具体代码如下:
///
/// SB过滤器 - 资源
///
public class SBResourceFilterAttribute : Attribute, IAsyncResourceFilter
{
public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
{
// 控制器实例化之前,执行的动作
// 验证是否跳过Api资源授权
// 缓存处理
await next();
// Action的Result Filter(befor)执行后再执行
}
}
方法过滤器,执行于控制器方法的前后置动作,前置动作可以应用于 参数传递
,后置动作可以应用于 Action审计日志
。具体代码如下:
///
/// SB过滤器 - 方法
///
public class SBActionFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// Action执行前,执行的动作
// 参数传递
var result = await next();
// Action的执行后,执行的动作
// Action审计日志
}
}
异常过滤器,作用于全局的异常处理,当系统发生未捕获异常时会触发此过滤器进行处理,应用于 全局异常捕获
、异常日志处理
。具体代码如下:
///
/// SB过滤器 - 全局异常
///
public class SBExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
if (context.ExceptionHandled)//异常是否已处理
return;
// 异常处理
context.Result = new ObjectResult(
new { code = "412", msg = "异常信息" });
// 处理完告诉系统此异常已处理
context.ExceptionHandled = true;
}
}
返回值过滤器,执行于结果执行之前/之后,前置动作可以应用于 Dto模型验证
,后置动作可以应用于 格式化返回值
。具体代码如下:
///
/// SB过滤器 - 返回值
///
public class SBResultFilter : IAsyncResultFilter
{
public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
// 结果执行前,执行的动作
// Dto模型验证
var result = await next();
// 结果执行后,执行的动作
// 格式化返回值
}
}
Asp.Net Core
中 过滤器 分为两种注册方式 全局
和 局部
,根据过滤器的使用场景及需要我们可以选择不同的注册方式。
过滤器也区分作用于全局和局部之分,作用于全局就不需要局部(类、控制器等)每一个进行代码注册,相对方便非常多。具体代码如下:
public void ConfigureServices(IServiceCollection services)
{
//...
services.AddMvc(options => {
options.Filters.Add();
options.Filters.Add();
options.Filters.Add();
options.Filters.Add();
options.Filters.Add();
});
//...
}
场景假设几大过滤器中有个过滤器只想作用于局部作用,过滤器可能就需要局部注册 ServiceFilter
和 TypeFilter
。
ps:几大过滤器没有继承 Attribute
不能使用特性的注册方式,想了解特性注册方式可以百度,暂时还没写。
ServiceFilter
和 TypeFilter
的区别:
ServiceFilter
和 TypeFilter
都实现了 IFilterFactory
。ServiceFilter
需要对自定义的 Filter
进行注册,TypeFilter
不需要。ServiceFilter
的 Filter
生命周期源自于注册方式,而 TypeFilter
每次都会创建一个新的实例。控制器中具体代码如下:
[ServiceFilter(typeof(SBAuthorizationFilterAttribute))]//过滤器注册到控制器中
[Route("api/[controller]")]
[ApiController]
public class DefaultController : ControllerBase
{
// GET: api/Default
[HttpGet]
[ServiceFilter(typeof(SBAuthorizationFilterAttribute))]//过滤器注册到方法中
public IEnumerable Get()
{
return new string[] { "value1", "value2" };
}
}
注册服务中具体代码如下:
public void ConfigureServices(IServiceCollection services)
{
//...
services.AddMvc();
// 注册过滤器服务,使用ServiceFilter 方式必须要注册 否则会报没有注册该服务的相关异常
services.AddSingleton();
//...
}
TypeFilter
的用法就比较方便,只要控制器或者方法注册即可。
[TypeFilter(typeof(SBAuthorizationFilterAttribute))]//过滤器注册到控制器中
[Route("api/[controller]")]
[ApiController]
public class DefaultController : ControllerBase
{
// GET: api/Default
[HttpGet]
[TypeFilter(typeof(SBAuthorizationFilterAttribute))]//过滤器注册到方法中
public IEnumerable Get()
{
return new string[] { "value1", "value2" };
}
}
- 全局->局部
- Controller->Action
- 先注册先调用