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
- 先注册先调用
相关文章推荐
- AOP系列(三)—Filter
- SharePoint解决方案开发模型系列 - 团队的建立
- CLR探索系列:System.Object内存布局模型及实现研究
- 人脸检测及识别python实现系列(3)——为模型训练准备人脸数据
- Django web开发系列(二)图书借阅管理系统之模型设计
- DirectShow系列讲座之三——开发自己的Filter
- MVC5学习系列——从控制器访问模型的数据(添加、修改、删除)
- 数学之美系列十六 -- 谈谈最大熵模型[zz]
- OO系统设计师之路--设计模型系列(1)--软件架构和软件框架[从老博客搬家至此]
- Sharepoin学习笔记—架构系列-- Sharepoint的数据模型(DataModel)、数据管理(Data Management)与查询(Query System)
- Spring MVC系列之模型绑定(SpringBoot)(七)
- keras系列︱Sequential与Model模型、keras基本结构功能(一)
- Sharepoint学习笔记 –架构系列—Sharepoint的客户端对象模型(Client Object Model)
- 线程模型、pthread 系列函数 和 简单多线程服务器端程序
- 机器学习实战系列:sklearn 中模型保存的两种方法
- Caffe学习系列:模型各层数据和参数可视化
- SpringCloud调研系列5.2:服务网关Zuul组合API之Filter研究
- C#进阶系列——AOP?AOP!
- springMVC笔记系列(14)——模型数据处理篇 之 Map
- ElasticSearch笔记系列(10)——子条件查询(下)Filter context