You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅对特定方法或控制器使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:17:29