.net 温故知新【16】:Asp.Net Core WebAPI 筛选器
一、筛选器
通过使用筛选器可在请求处理管道中的特定阶段之前或之后运行代码。
这即是我们经常听到的面向切面编程AOP(Aspect Oriented Programming)技术,AOP通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。
筛选器在 ASP.NET Core 操作调用管道(有时称为筛选器管道)内运行。 筛选器管道在 ASP.NET Core 选择了要执行的操作之后运行:
Asp.Net Core 关注的切面点 包括错误处理、缓存、配置、授权和日志记录筛选器,这个是说通过筛选器可以实现对以上关注点的一些操作。
在Asp.Net Core中有如下几种类型的筛选器:

其中部分是内置筛选器,比如授权,响应缓存已经帮我们内置进了框架,我们只需要配置即可使用;其他筛选器是可以自定义处理逻辑的。
下图展示了筛选器类型在筛选器管道中的交互方式和执行顺序:

二、操作型筛选器
第一部分主要是对筛选器的一个梳理,有些重点的提炼,详情查看文档,因为文档部分理解起来比较晦涩,比如关注点是关注点,知识说筛选器可以对这些关注点启到作用,筛选器是固定的几种,不要被文档中的这种描述搞晕了,一会儿有这几种,怎么到下面又是另外几种,要注意区分重点。
操作筛选器可以实现接口IActionFilter,在接口中有两个方法,OnActionExecuting 在调用操作方法之前执行。 OnActionExecuted 在操作方法返回之后执行。
- 先建WebAPI项目 WebAPI_Filter
- 建一个 FilterController,并创建Get请求Test
namespace WebAPI_Filter.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class FilterController : ControllerBase
{
[HttpGet]
public string Test()
{
return "测试Filter!";
}
}
}
- 创建ActionFilter 筛选器
namespace WebAPI_Filter.Filter
{
public class MyActionFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine(context.HttpContext.Request.GetDisplayUrl()+ " 执行之后!");
}
public void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine(context.HttpContext.Request.GetDisplayUrl() + " 执行之前!");
}
}
}
- 在Program.cs里面添加筛选器

执行测试接口

三、筛选器作用域和执行顺序
上面直接在Program.cs里面添加筛选器的方式称为全局筛选器,所有控制器、操作都会受全局筛选器影响。还有一种筛选器实现方式是属性筛选器,通过继承属性类然后将属性标签放置在控制器或者操作上。
新建两个属性类MyAttributeFilter 用于Controller控制器类,MyOPAttributeFilter用于操作方法上。
public class MyAttributeFilter: ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine(context.HttpContext.Request.GetDisplayUrl() + " 控制器之后-筛选器属性!");
}
public override void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine(context.HttpContext.Request.GetDisplayUrl() + " 控制器之前-筛选器属性!");
}
}
public class MyOPAttributeFilter : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine(context.HttpContext.Request.GetDisplayUrl() + " 操作之后-筛选器属性!");
}
public override void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine(context.HttpContext.Request.GetDisplayUrl() + " 操作之前-筛选器属性!");
}
}

加上之前的全局筛选器,我们一共有三个作用域的筛选器,现在我们测试看看筛选器的执行顺序。

则可总结出不同作用域筛选器的执行顺序:
全局筛选器的 before 代码。
控制器筛选器的 before 代码。
操作方法筛选器的 before 代码。
操作方法筛选器的 after 代码。
控制器筛选器的 after 代码。
全局筛选器的 after 代码。
当然可以通过 Order 属性来确定执行顺序,在全局或者属性筛选器里面设置 Order 值,值越小执行优先级越高。

四、筛选器依赖注入
可按类型或实例添加筛选器。 如果添加实例,该实例将用于每个请求。
其中builder.Services.AddControllers(options => options.Filters.Add<MyActionFilter>())即为按实例添加,该MyActionFilter用于每个请求。
如果添加类型,则将激活该类型。 激活类型的筛选器意味着:第一种是为每个请求创建一个实例,第二种依赖关系注入 (DI) 将填充所有构造函数依赖项。
上面位置我们是为每个请求创建一个实例,这样的话无法使用依赖注入体系为我们自动注入,因为因为属性在应用时必须提供自己的构造函数参数,该参数需要手动指定。
比如我们想在操作方法的MyOPAttributeFilter筛选属性 注入IHostEnvironment:
public class MyOPAttributeFilter : ActionFilterAttribute
{
IHostEnvironment hostEnvironment;
public MyOPAttributeFilter(IHostEnvironment _hostEnvironment)
{
hostEnvironment = _hostEnvironment;
}
public override void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine(context.HttpContext.Request.GetDisplayUrl() + " 操作之后-筛选器属性!");
}
public override void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine(context.HttpContext.Request.GetDisplayUrl() + " 操作之前-筛选器属性!");
//打印环境变量
Console.WriteLine(hostEnvironment.EnvironmentName);
}
}
这个时候直接就报错提示需要参数,而我们想的是通过依赖注入配置。

框架提供以下筛选器支持从 DI 提供的构造函数依赖项:
- ServiceFilterAttribute
- TypeFilterAttribute
- 在属性上实现 IFilterFactory。
TypeFilterAttribute:不会直接从 DI 容器解析其类型。Microsoft.Extensions.DependencyInjection.ObjectFactory 对类型进行实例化,所以不需要先将MyOPAttributeFilter加入容器,直接使用:
[TypeFilter(typeof(MyOPAttributeFilter))]

ServiceFilterAttribute 使用需要先将MyOPAttributeFilter注入到容器,然后再使用。

以上就是关于AOP切面编程和筛选器的梳理,其他类型的筛选器和细节可查询官方文档:ASP.NET Core 中的筛选器
.net 温故知新【16】:Asp.Net Core WebAPI 筛选器的更多相关文章
- Asp.Net Core WebApi学习笔记(四)-- Middleware
Asp.Net Core WebApi学习笔记(四)-- Middleware 本文记录了Asp.Net管道模型和Asp.Net Core的Middleware模型的对比,并在上一篇的基础上增加Mid ...
- Asp.net core WebApi 使用Swagger生成帮助页实例
最近我们团队一直进行.net core的转型,web开发向着前后端分离的技术架构演进,我们后台主要是采用了asp.net core webapi来进行开发,开始每次调试以及与前端人员的沟通上都存在这效 ...
- 零基础ASP.NET Core WebAPI团队协作开发
零基础ASP.NET Core WebAPI团队协作开发 相信大家对“前后端分离”和“微服务”这两个词应该是耳熟能详了.网上也有很多介绍这方面的文章,写的都很好.我这里提这个是因为接下来我要分享的内容 ...
- 记一次使用Asp.Net Core WebApi 5.0+Dapper+Mysql+Redis+Docker的开发过程
#前言 我可能有三年没怎么碰C#了,目前的工作是在全职搞前端,最近有时间抽空看了一下Asp.net Core,Core版本号都到了5.0了,也越来越好用了,下面将记录一下这几天以来使用Asp.Net ...
- asp.net core webapi之跨域(Cors)访问
这里说的跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被当作 ...
- ASP.NET Core WebAPI 开发-新建WebAPI项目
ASP.NET Core WebAPI 开发-新建WebAPI项目, ASP.NET Core 1.0 RC2 即将发布,我们现在来学习一下 ASP.NET Core WebAPI开发. 网上已经有泄 ...
- Asp.net Core WebApi 使用Swagger做帮助文档,并且自定义Swagger的UI
WebApi写好之后,在线帮助文档以及能够在线调试的工具是专业化的表现,而Swagger毫无疑问是做Docs的最佳工具,自动生成每个Controller的接口说明,自动将参数解析成json,并且能够在 ...
- Asp.net core WebApi 使用Swagger生成帮助页
最近我们团队一直进行.net core的转型,web开发向着前后端分离的技术架构演进,我们后台主要是采用了asp.net core webapi来进行开发,开始每次调试以及与前端人员的沟通上都存在这效 ...
- ASP.Net Core WebApi几种版本控制对比
版本控制的好处: (1)助于及时推出功能, 而不会破坏现有系统. (2)它还可以帮助为选定的客户提供额外的功能. API 版本控制可以采用不同的方式进行控制,方法如下: (1)在 URL 中追加版本或 ...
- ASP.NET Core WebApi 返回统一格式参数(Json 中 Null 替换为空字符串)
相关博文:ASP.NET Core WebApi 返回统一格式参数 业务场景: 统一返回格式参数中,如果包含 Null 值,调用方会不太好处理,需要替换为空字符串,示例: { "respon ...
随机推荐
- Leetcode刷题笔记——单调性
单调性 单调性是数学中使用的一种常见性质,通常用于描述函数,在高等数学中的定义常常为: 设函数f(x)在区间I上有定义,如果对于I上的任意两个数x1和x2,当x1<x2时,有f(x1)<f ...
- 升级java11后,maven命令打包报错
一.问题 升级java11后,maven命令打包报错: mvn clean package -Dmaven.test.skip=true [ERROR] Failed to execute goal ...
- 「codeforces - 1208F」Bits and Pieces
link. 考虑把原问题写成一个在 \(\left(\log_2 \max v \right) \times n\) 的矩阵里选出三列,我们首先预处理出 \(j \cap q\).具体,我们需要对于每 ...
- MPI转以太网Plus模块Modbus连接两台变频器通信案例
MPI转以太网Plus模块Modbus主站连接两台变频器通信案例 MPI转以太网Plus模块连接200PLC无需编程实现Modbus主从站功能与2台变频器modbus通信:以下就是MPI转以太网模块作 ...
- vue2实现饼图Pie组件封装
实现如下效果: 效果展示:https://code.juejin.cn/pen/7226656439941955644 如果不会请移步到官网的栗子,请点击查看 直接给大家上代码: 整体代码片段 1 & ...
- antd/fusion表格增加圈选复制功能
背景介绍 我们存在着大量在PC页面通过表格看数据业务场景,表格又分为两种,一种是 antd / fusion 这种基于 dom 元素的表格,另一种是通过 canvas 绘制的类似 excel 的表格. ...
- Redis系列24:Redis使用规范
Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...
- linux的进阶命令
一. linux的基础命令 1.history 查看历史命令记录 2.ifconfig 查看所在的IP地址 3.tail -n 查看一个文件的后n行记录 4.head -n 查看一个文件的前n行记录5 ...
- 使用 Alacritty 替代 Gnome-Terminal 解决 Ubuntu 中终端的行间距问题
我之前发了一篇随笔新版 Ubuntu 中 gnome-terminal 可恶的行间距问题逼我退回了 Ubuntu 20.04,描述了新版 Ubuntu 中终端的行间距问题.评论中给出了一个解决办法,那 ...
- DB22
IBM官方网站提供了DB2 Express-C版本的软件免费下载: 下载地址 : http://www.ibm.com/developerworks/cn/downloads/im/udbexp/
