您的位置:首页 > 运维架构

AOP系列之Filter管道模型

2020-06-29 04:59 1156 查看

一、前言

Filter
是延续
Asp.Net Mvc
的产物,同样保留了五种的
Filter
,分别是
Authorization Filter
Resource Filter
Action Filter
Exception Filter
Result Filter
。通过不同的
Filter
可以有效处理一些共通的动作。

(一)Filter 介绍

  • Authorization Filter:优先级1;权限过滤器,通常在
    Filter Pipleline
    中首先执行,并用于决定当前客户端
    Request
    请求权限的身份授权验证
  • Resource Filter:优先级2;资源过滤器,通常在
    Authorization
    后面执行,同时在后面的其它过滤器完成后还会执行;作用于
    Api
    资源授权、缓存处理等一些可以性能原因的拦截,因为运行在模型绑定前,所以这里的操作都会影响模型绑定。
  • Action Filter:优先级3;方法过滤器,执行于
    Action
    方法前后,用于
    Action
    审计日志、传递参数和方法返回值的处理。
  • Exception Filter:优先级4;异常过滤器,被应用全局策略处理未处理的异常被写入响应体。
  • Result Filter:优先级5;返回值过滤器,可以执行于
    Action
    结果之前执行,且执行
    Action
    成功后执行,使用逻辑一般围绕
    Action
    入参的验证和格式化返回值。

(二)Filter 流程图

二、Filter 实现&场景应用

在开始写代码前需引用nuget包或包含的集成包

Microsoft.AspNetCore.Mvc.Abstractions
均可;下面我用异步的方式,继承相应过滤器实现对应功能,说这么多,还是看代码吧!

(一)Authorization Filter

权限过滤器,通过

Authorization Filter
可以实现复杂的
防篡改
验证XsrfToken防伪令牌
等操作。具体代码如下:

/// <summary>
/// SB过滤器 - 权限
/// </summary>
public class SBAuthorizationFilterAttribute : Attribute, IAsyncAuthorizationFilter
{
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{

// 参数防篡改

// 验证XsrfToken防伪令牌

// ..

}
}

(二)Resource Filter

资源过滤器,通过

Resource Filter
可以进行
Api资源授权
缓存处理
等复杂操作。具体代码如下:

/// <summary>
/// SB过滤器 - 资源
/// </summary>
public class SBResourceFilterAttribute : Attribute, IAsyncResourceFilter
{
public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
{
// 控制器实例化之前,执行的动作

// 验证是否跳过Api资源授权

// 缓存处理

await next();

// Action的Result Filter(befor)执行后再执行

}
}

(三)Action Filter

方法过滤器,执行于控制器方法的前后置动作,前置动作可以应用于

参数传递
,后置动作可以应用于
Action审计日志
。具体代码如下:

/// <summary>
/// SB过滤器 - 方法
/// </summary>
public class SBActionFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{

// Action执行前,执行的动作

// 参数传递

var result = await next();

// Action的执行后,执行的动作

// Action审计日志

}
}

(四)Exception Filter

异常过滤器,作用于全局的异常处理,当系统发生未捕获异常时会触发此过滤器进行处理,应用于

全局异常捕获
异常日志处理
。具体代码如下:

/// <summary>
/// SB过滤器 - 全局异常
/// </summary>
public class SBExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{

if (context.ExceptionHandled)//异常是否已处理
return;

// 异常处理
context.Result = new ObjectResult(
new { code = "412", msg = "异常信息" });

// 处理完告诉系统此异常已处理
context.ExceptionHandled = true;
}
}

(五)Result Filter

返回值过滤器,执行于结果执行之前/之后,前置动作可以应用于

Dto模型验证
,后置动作可以应用于
格式化返回值
。具体代码如下:

/// <summary>
/// SB过滤器 - 返回值
/// </summary>
public class SBResultFilter : IAsyncResultFilter
{
public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{

// 结果执行前,执行的动作

// Dto模型验证

var result = await next();

// 结果执行后,执行的动作

// 格式化返回值

}
}

三、Asp.Net Core 过滤器的注册方式

Asp.Net Core
过滤器 分为两种注册方式
全局
局部
,根据过滤器的使用场景及需要我们可以选择不同的注册方式。

(一)全局注册

过滤器也区分作用于全局和局部之分,作用于全局就不需要局部(类、控制器等)每一个进行代码注册,相对方便非常多。具体代码如下:

public void ConfigureServices(IServiceCollection services)
{
//...

services.AddMvc(options => {
options.Filters.Add<SBAuthorizationFilterAttribute>();
options.Filters.Add<SBResourceFilterAttribute>();
options.Filters.Add<SBActionFilter>();
options.Filters.Add<SBExceptionFilter>();
options.Filters.Add<SBResultFilter>();
});

//...
}

(二)局部注册

场景假设几大过滤器中有个过滤器只想作用于局部作用,过滤器可能就需要局部注册

ServiceFilter
TypeFilter

ps:几大过滤器没有继承
Attribute
不能使用特性的注册方式,想了解特性注册方式可以百度,暂时还没写。

ServiceFilter
TypeFilter
的区别:

  • ServiceFilter
    TypeFilter
    都实现了
    IFilterFactory
  • ServiceFilter
    需要对自定义的
    Filter
    进行注册,
    TypeFilter
    不需要。
  • ServiceFilter
    Filter
    生命周期源自于注册方式,而
    TypeFilter
    每次都会创建一个新的实例。

1. ServiceFilter 使用方式

控制器中具体代码如下:

[ServiceFilter(typeof(SBAuthorizationFilterAttribute))]//过滤器注册到控制器中
[Route("api/[controller]")]
[ApiController]
public class DefaultController : ControllerBase
{
// GET: api/Default
[HttpGet]
[ServiceFilter(typeof(SBAuthorizationFilterAttribute))]//过滤器注册到方法中
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}

注册服务中具体代码如下:

public void ConfigureServices(IServiceCollection services)
{
//...

services.AddMvc();

// 注册过滤器服务,使用ServiceFilter 方式必须要注册 否则会报没有注册该服务的相关异常
services.AddSingleton<SBAuthorizationFilterAttribute>();

//...
}

2. TypeFilter 使用方式

TypeFilter
的用法就比较方便,只要控制器或者方法注册即可。

[TypeFilter(typeof(SBAuthorizationFilterAttribute))]//过滤器注册到控制器中
[Route("api/[controller]")]
[ApiController]
public class DefaultController : ControllerBase
{
// GET: api/Default
[HttpGet]
[TypeFilter(typeof(SBAuthorizationFilterAttribute))]//过滤器注册到方法中
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}

四、Asp.Net Core 过滤器调用顺序

  • 全局->局部
  • Controller->Action
  • 先注册先调用

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: