前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >.net 温故知新【16】:Asp.Net Core WebAPI 筛选器

.net 温故知新【16】:Asp.Net Core WebAPI 筛选器

作者头像
SpringSun
发布2023-12-19 09:40:47
1570
发布2023-12-19 09:40:47
举报
文章被收录于专栏:技术赋能学术技术赋能学术

一、筛选器

通过使用筛选器可在请求处理管道中的特定阶段之前或之后运行代码。

这即是我们经常听到的面向切面编程AOP(Aspect Oriented Programming)技术,AOP通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。

筛选器在 ASP.NET Core 操作调用管道(有时称为筛选器管道)内运行。 筛选器管道在 ASP.NET Core 选择了要执行的操作之后运行:

image
image

Asp.Net Core 关注的切面点 包括错误处理、缓存、配置、授权和日志记录筛选器,这个是说通过筛选器可以实现对以上关注点的一些操作。

在Asp.Net Core中有如下几种类型的筛选器:

image
image

其中部分是内置筛选器,比如授权,响应缓存已经帮我们内置进了框架,我们只需要配置即可使用;其他筛选器是可以自定义处理逻辑的。

下图展示了筛选器类型在筛选器管道中的交互方式和执行顺序:

image
image

二、操作型筛选器

第一部分主要是对筛选器的一个梳理,有些重点的提炼,详情查看文档,因为文档部分理解起来比较晦涩,比如关注点是关注点,知识说筛选器可以对这些关注点启到作用,筛选器是固定的几种,不要被文档中的这种描述搞晕了,一会儿有这几种,怎么到下面又是另外几种,要注意区分重点。

操作筛选器可以实现接口IActionFilter,在接口中有两个方法,OnActionExecuting 在调用操作方法之前执行。 OnActionExecuted 在操作方法返回之后执行。

  • 先建WebAPI项目 WebAPI_Filter
  • 建一个 FilterController,并创建Get请求Test
代码语言:javascript
复制
namespace WebAPI_Filter.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class FilterController : ControllerBase
    {
        [HttpGet]
        public string Test()
        {
            return "测试Filter!";
        }
    }
}
  • 创建ActionFilter 筛选器
代码语言:javascript
复制
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里面添加筛选器
image
image

执行测试接口

image
image

三、筛选器作用域和执行顺序

上面直接在Program.cs里面添加筛选器的方式称为全局筛选器,所有控制器、操作都会受全局筛选器影响。还有一种筛选器实现方式是属性筛选器,通过继承属性类然后将属性标签放置在控制器或者操作上。

新建两个属性类MyAttributeFilter 用于Controller控制器类,MyOPAttributeFilter用于操作方法上。

代码语言:javascript
复制
    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() + "  操作之前-筛选器属性!");
        }
    }
image
image

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

image
image

则可总结出不同作用域筛选器的执行顺序:

代码语言:javascript
复制
全局筛选器的 before 代码。
	控制器筛选器的 before 代码。
		操作方法筛选器的 before 代码。
		操作方法筛选器的 after 代码。
	控制器筛选器的 after 代码。
全局筛选器的 after 代码。

当然可以通过 Order 属性来确定执行顺序,在全局或者属性筛选器里面设置 Order 值,值越小执行优先级越高。

image
image

四、筛选器依赖注入

可按类型或实例添加筛选器。 如果添加实例,该实例将用于每个请求。

其中builder.Services.AddControllers(options => options.Filters.Add<MyActionFilter>())即为按实例添加,该MyActionFilter用于每个请求。

如果添加类型,则将激活该类型。 激活类型的筛选器意味着:第一种是为每个请求创建一个实例,第二种依赖关系注入 (DI) 将填充所有构造函数依赖项。

上面位置我们是为每个请求创建一个实例,这样的话无法使用依赖注入体系为我们自动注入,因为因为属性在应用时必须提供自己的构造函数参数,该参数需要手动指定。

比如我们想在操作方法的MyOPAttributeFilter筛选属性 注入IHostEnvironment:

代码语言:javascript
复制
    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);
        }
    }

这个时候直接就报错提示需要参数,而我们想的是通过依赖注入配置。

image
image

框架提供以下筛选器支持从 DI 提供的构造函数依赖项:

  • ServiceFilterAttribute
  • TypeFilterAttribute
  • 在属性上实现 IFilterFactory。

TypeFilterAttribute:不会直接从 DI 容器解析其类型。Microsoft.Extensions.DependencyInjection.ObjectFactory 对类型进行实例化,所以不需要先将MyOPAttributeFilter加入容器,直接使用:

代码语言:javascript
复制
[TypeFilter(typeof(MyOPAttributeFilter))]
image
image

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

image
image

以上就是关于AOP切面编程和筛选器的梳理,其他类型的筛选器和细节可查询官方文档:ASP.NET Core 中的筛选器

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-12-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、筛选器
  • 二、操作型筛选器
  • 三、筛选器作用域和执行顺序
  • 四、筛选器依赖注入
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档