在C#的ASP.NET Core开发中,请求过滤是处理通用前置逻辑的核心手段,既可以通过Middleware实现管道级别的全局过滤,也可以通过ActionFilter实现控制器或接口级别的精准过滤,两者结合能满足绝大多数业务场景的需求。

Middleware过滤器的基础创建
Middleware是ASP.NET Core请求管道的核心组件,所有请求都会经过注册的中间件,适合实现全局通用的过滤逻辑,比如全局请求日志、跨域处理、全局异常捕获等。
自定义Middleware类
首先创建一个独立的Middleware类,需要包含RequestDelegate类型的构造函数参数,以及InvokeAsync方法用于处理请求上下文。
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
public class GlobalRequestFilterMiddleware
{
private readonly RequestDelegate _next;
// 构造函数接收下一个中间件的委托
public GlobalRequestFilterMiddleware(RequestDelegate next)
{
_next = next;
}
// 处理请求的核心方法
public async Task InvokeAsync(HttpContext context)
{
// 请求进入时的过滤逻辑,比如记录请求路径
var requestPath = context.Request.Path;
// 这里可以添加鉴权、参数校验等逻辑
// 如果校验不通过,可以直接返回响应,不调用下一个中间件
// if (校验失败)
// {
// context.Response.StatusCode = 401;
// await context.Response.WriteAsync("请求校验失败");
// return;
// }
// 调用下一个中间件
await _next(context);
// 响应返回时的处理逻辑,比如记录响应状态码
var responseStatusCode = context.Response.StatusCode;
}
}
注册Middleware到管道
创建完成后需要在Program.cs中注册该中间件,注册顺序决定了中间件的执行顺序,越早注册的中间件越先处理请求,越晚处理响应。
var builder = WebApplication.CreateBuilder(args); // 添加控制器服务 builder.Services.AddControllers(); var app = builder.Build(); // 注册自定义Middleware,放在UseAuthorization之前或之后根据业务需求调整 app.UseMiddleware<GlobalRequestFilterMiddleware>(); app.UseAuthorization(); app.MapControllers(); app.Run();
ActionFilter进阶使用技巧
ActionFilter是ASP.NET Core提供的过滤器,作用于MVC的控制器和接口层面,比Middleware更精准,适合实现接口级别的鉴权、参数校验、结果处理等逻辑。
自定义ActionFilter类
实现IActionFilter或IAsyncActionFilter接口,前者是同步方法,后者是异步方法,实际开发中更推荐使用异步版本避免阻塞。
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Threading.Tasks;
public class CustomActionFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// 动作执行前的逻辑,比如校验请求参数
var actionArguments = context.ActionArguments;
// 示例:校验必传参数是否存在
if (!actionArguments.ContainsKey("id"))
{
context.Result = new BadRequestObjectResult("缺少必传参数id");
return;
}
// 执行下一个过滤器或者实际的接口方法
var executedContext = await next();
// 动作执行后的逻辑,比如处理返回结果
if (executedContext.Exception != null)
{
// 处理接口执行过程中的异常
executedContext.ExceptionHandled = true;
executedContext.Result = new ObjectResult("接口执行异常")
{
StatusCode = 500
};
}
}
}
ActionFilter的注册方式
ActionFilter支持多种注册方式,包括全局注册、控制器级别注册、接口级别注册,满足不同粒度的过滤需求。
全局注册
在Program.cs中通过AddControllers的配置全局注册,所有接口都会生效。
var builder = WebApplication.CreateBuilder(args);
// 全局注册ActionFilter
builder.Services.AddControllers(options =>
{
options.Filters.Add<CustomActionFilter>();
});
var app = builder.Build();
app.UseAuthorization();
app.MapControllers();
app.Run();
局部注册
在控制器或者具体的接口方法上通过[TypeFilter]或者[ServiceFilter]特性注册,仅对标记的控制器或接口生效。
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
[ApiController]
[Route("api/[controller]")]
// 控制器级别注册,该控制器下所有接口都会生效
[TypeFilter(typeof(CustomActionFilter))]
public class UserController : ControllerBase
{
[HttpGet("{id}")]
// 接口级别注册,仅该接口生效
[TypeFilter(typeof(CustomActionFilter))]
public async Task<IActionResult> GetUser(int id)
{
await Task.CompletedTask;
return Ok(new { Id = id, Name = "测试用户" });
}
}
过滤顺序控制与参数传递
当同时存在多个Middleware和ActionFilter时,执行顺序需要明确控制,同时过滤器之间可能需要传递自定义参数。
执行顺序规则
Middleware的执行顺序是注册顺序的正序,响应阶段是反序;ActionFilter的执行顺序优先级为:全局注册 > 控制器级别 > 接口级别,同级别的过滤器可以通过实现IOrderedFilter接口设置Order属性调整顺序,Order值越小越先执行。
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Threading.Tasks;
// 设置Order为1,比默认Order(0)的过滤器后执行
public class OrderTestFilter : IAsyncActionFilter, IOrderedFilter
{
public int Order => 1;
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// 处理逻辑
await next();
}
}
过滤器参数传递
如果需要在注册过滤器时传递自定义参数,可以使用TypeFilter的特性构造函数传参,或者自定义过滤器工厂。
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Threading.Tasks;
// 支持接收参数的ActionFilter
public class ParamActionFilter : IAsyncActionFilter
{
private readonly string _filterName;
public ParamActionFilter(string filterName)
{
_filterName = filterName;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// 使用传入的参数
var param = _filterName;
await next();
}
}
[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
[HttpGet]
// 传递参数给过滤器
[TypeFilter(typeof(ParamActionFilter), Arguments = new object[] { "自定义过滤参数" })]
public IActionResult Test()
{
return Ok();
}
}
两种过滤方式的适用场景对比
实际开发中需要根据需求选择合适的过滤方式,以下是两者的核心差异对比:
| 对比维度 | Middleware | ActionFilter |
|---|---|---|
| 作用范围 | 整个请求管道,所有请求都会经过 | 仅MVC/API的控制器和接口层面 |
| 可获取的信息 | 仅HttpContext,无法获取控制器、接口相关的元数据 | 可以获取控制器、接口方法、参数、返回结果等完整元数据 |
| 适用场景 | 全局日志、跨域、全局异常、通用请求头处理 | 接口鉴权、参数校验、接口级别的结果处理、接口耗时统计 |
在实际项目中,通常会将两者结合使用,比如用Middleware处理全局的跨域和通用异常,用ActionFilter处理接口级别的鉴权和参数校验,既能保证通用逻辑的统一处理,又能满足不同接口的个性化需求。
C#ActionFilterMiddleware请求过滤修改时间:2026-07-16 12:45:34