在 ASP.NET Core Web API 中使用操作筛选器统一处理通用操作

前言:什么是操作筛选器

操作筛选器是 ASP.NET Core Web API 中的一种过滤器,用于在执行控制器操作(Action)之前或之后执行一些代码,完成特定的功能,比如执行日志记录、身份验证、授权、异常处理等通用的处理逻辑。

每次 ASP.NET Core Web API 中控制器的操作方法被执行的时候,操作筛选器都会被执行,所以操作筛选器默认是应用于所有控制器的操作方法的。

一个项目中可以注册多个操作筛选器,这些操作筛选器组成一个链,上一个筛选器执行完了再执行下一个。next 就是一个用来指向下一个操作筛选器的委托,如果当前的操作筛选器是最后一个筛选器的话,next 就会执行要执行的操作方法。

操作筛选器跟前文(见《如何在 ASP.NET Core Web API 方法执行前后 "偷偷" 作一些 "坏" 事?初识 ActionFilterAttribute》)讲过的 ActionFilterAttribute 比较相似,ActionFilterAttribute 是用于将操作筛选器逻辑应用于控制器操作的一种方式,而操作筛选器是一种更广泛的概念,可以说,ActionFilterAttribute 是操作筛选器的一种特定实现方式,它通过特性的方式将操作筛选器逻辑应用于控制器操作。

Step By Step 步骤

  1. 创建一个 ASP.NET Core Web API 项目

  2. 编写两个自定义的操作筛选器 MyActionFilter1 和 MyActionFilter2,实现 IAsyncActionFilter 接口(注意看代码中的注释

    c# 复制代码
    using Microsoft.AspNetCore.Mvc.Filters;
    
    public class MyActionFilter1 : IAsyncActionFilter
    {
    	// context 参数代表 Action 执行的上下文对象,从 context 中我们可以获取请求的路径、参数值等信息
    	// next 参数代表下一个要执行的操作筛选器
    	public async Task OnActionExecutionAsync(
    		ActionExecutingContext context, 
    		ActionExecutionDelegate next)
    	{
    		// next 之前的代码是在操作方法执行之前要执行的代码
    		Console.WriteLine("MyActionFilter 1:开始执行");
    
    		// 用 next 来执行下一个操作筛选器,
    		// 如果这是最后一个操作筛选器,它就会执行实际的操作方法
    		// next 的返回值是操作方法的执行结果,返回值是 ActionExecutedContext 类型的。
    		// 如果操作方法执行的时候出现了未处理异常,
    		// 那么 ActionExecutedContext 的 Exception 属性就是异常对象,
    		// ActionExecutedContext 的 Result 属性就是操作方法的执行结果。
    		ActionExecutedContext r = await next();
    		
    		// 以下代码则是在操作方法执行之后要执行的代码
    		if (r.Exception != null)
    		{
    			Console.WriteLine("MyActionFilter 1:执行失败");
    		}
    		else
    		{
    			Console.WriteLine("MyActionFilter 1:执行成功");
    		}
    	}
    }
    
    public class MyActionFilter2 : IAsyncActionFilter
    {
    	public async Task OnActionExecutionAsync(
    		ActionExecutingContext context, 
    		ActionExecutionDelegate next)
    	{
    		Console.WriteLine("MyActionFilter 2:开始执行");
    		ActionExecutedContext r = await next();
    		if (r.Exception != null)
    		{
    			Console.WriteLine("MyActionFilter 2:执行失败");
    		}
    		else
    		{
    			Console.WriteLine("MyActionFilter 2:执行成功");
    		}
    	}
    }
  3. 打开 Program.cs,注册这两个操作筛选器

    c# 复制代码
    using Microsoft.AspNetCore.Mvc;
    
    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    
    builder.Services.AddControllers();
    // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();
    
    // 注册操作筛选器服务
    builder.Services.Configure<MvcOptions>(options => {
    	options.Filters.Add<MyActionFilter1>();
    	options.Filters.Add<MyActionFilter2>();
    });
    
    var app = builder.Build();
    
    // Configure the HTTP request pipeline.
    if (app.Environment.IsDevelopment())
    {
    	app.UseSwagger();
    	app.UseSwaggerUI();
    }
    
    app.UseHttpsRedirection();
    
    app.UseAuthorization();
    
    app.MapControllers();
    
    app.Run();
  4. 打开控制器,增加一个用于测试的操作方法

    c# 复制代码
    using Microsoft.AspNetCore.Mvc;
    
    namespace 操作筛选器.Controllers
    {
    	[ApiController]
    	[Route("[controller]/[action]")]
    	public class TestController : ControllerBase
    	{
    		[HttpGet]
    		public string GetData()
    		{
    			Console.WriteLine("执行GetData");
    			return "yzk";
    		}
    	}
    }

测试运行和结果

执行顺序:
MyActionFilter 1:开始执行
MyActionFilter 2:开始执行
执行GetData
MyActionFilter 2:执行成功
MyActionFilter 1:执行成功
相关推荐
ZSYP-S5 分钟前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
Yuan_o_1 小时前
Linux 基本使用和程序部署
java·linux·运维·服务器·数据库·后端
fkdw1 小时前
C# Newtonsoft.Json 反序列化派生类数据丢失问题
c#·json
程序员一诺1 小时前
【Python使用】嘿马python高级进阶全体系教程第10篇:静态Web服务器-返回固定页面数据,1. 开发自己的静态Web服务器【附代码文档】
后端·python
DT辰白2 小时前
如何解决基于 Redis 的网关鉴权导致的 RESTful API 拦截问题?
后端·微服务·架构
thatway19892 小时前
AI-SoC入门:15NPU介绍
后端
陶庵看雪2 小时前
Spring Boot注解总结大全【案例详解,一眼秒懂】
java·spring boot·后端
Q_19284999063 小时前
基于Spring Boot的图书管理系统
java·spring boot·后端
ss2733 小时前
基于Springboot + vue实现的汽车资讯网站
vue.js·spring boot·后端
一只IT攻城狮3 小时前
华为云语音交互SIS的使用案例(文字转语音-详细教程)
java·后端·华为云·音频·语音识别