如何仅对特定方法或控制器使用IEndpointFilter?
如何在ASP.NET Core中为特定路由/控制器应用IEndpointFilter
如果你不想让IEndpointFilter全局生效,有两种针对性的实现方式:
一、仅应用于特定路由
1. 单个路由单独配置
在定义具体路由时,直接给该路由添加过滤器,而非全局的MapControllers():
// 仅对"/api/ampersand"这个Get路由应用过滤器 app.MapGet("/api/ampersand", (HttpContext context) => { return Results.Ok("Filtered route response"); }) .AddEndpointFilter(new AmpersandEndpointFilter());
2. 路由组批量配置
如果有一组路由需要共用过滤器,可以先创建路由组,再给组添加过滤器,组内所有路由都会自动继承:
// 创建路由组 var filteredGroup = app.MapGroup("/api/filtered"); // 给组添加过滤器 filteredGroup.AddEndpointFilter(new AmpersandEndpointFilter()); // 组内的所有路由都会应用该过滤器 filteredGroup.MapGet("/users", () => Results.Ok(new List<string> { "Alice", "Bob" })); filteredGroup.MapPost("/users", (User user) => Results.Created($"/api/filtered/users/{user.Id}", user));
二、仅应用于特定控制器
如果需要针对整个控制器生效,可以通过特性标记+过滤器内部判断或控制器约定两种方式实现:
1. 特性标记+过滤器判断
步骤1:定义标记特性
[AttributeUsage(AttributeTargets.Class)] public class UseAmpersandFilterAttribute : Attribute { }
步骤2:给目标控制器添加特性
[UseAmpersandFilter] public class TargetController : ControllerBase { [HttpGet("/api/target")] public IActionResult Get() { return Ok("From TargetController"); } }
步骤3:修改过滤器逻辑,仅处理标记了特性的控制器
public class AmpersandEndpointFilter : IEndpointFilter { public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next) { // 检查当前端点是否属于标记了UseAmpersandFilter的控制器 var endpoint = context.HttpContext.GetEndpoint(); var isTargetController = endpoint?.Metadata .OfType<ControllerActionDescriptor>() .Any(desc => desc.ControllerTypeInfo.GetCustomAttribute<UseAmpersandFilterAttribute>() != null) ?? false; if (!isTargetController) { // 非目标控制器,直接跳过过滤器逻辑 return await next(context); } // 执行你的过滤器核心逻辑 // 示例:打印请求路径 Console.WriteLine($"Filtered request: {context.HttpContext.Request.Path}"); // 继续执行后续管道 return await next(context); } }
步骤4:全局注册过滤器(此时过滤器会自动过滤非目标控制器)
app.MapControllers() .AddEndpointFilter(new AmpersandEndpointFilter());
2. 控制器约定方式
通过实现IControllerModelConvention,自动给指定控制器添加过滤器,无需全局注册过滤器:
步骤1:实现控制器约定
public class AmpersandFilterConvention : IControllerModelConvention { public void Apply(ControllerModel controller) { // 匹配目标控制器,可以按名称、命名空间等条件筛选 if (controller.ControllerType.Name.Equals("TargetController", StringComparison.OrdinalIgnoreCase)) { // 给该控制器的所有Action添加过滤器 controller.Filters.Add(new AmpersandEndpointFilter()); } } }
步骤2:注册约定到MVC配置
builder.Services.AddControllers(options => { options.Conventions.Add(new AmpersandFilterConvention()); });
这种方式下,只有匹配的控制器会应用过滤器,其他控制器不受影响。
内容的提问来源于stack exchange,提问作者Gargoyle
相关产品推荐
相关产品推荐

