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

如何判断Endpoint是否为ApiController?寻求Middleware路由识别更优方案

从EndpointDataSource识别ApiController路由的方案

核心结论

是的,从EndpointDataSource获取的Endpoint实例包含可标识该路由是否对应ApiController的信息,通过Endpoint的**元数据(Metadata)**即可实现准确判断,比路径匹配更健壮、解耦。

判断逻辑原理

当控制器标记了[ApiController]特性时,ASP.NET Core会将相关元数据附加到对应的Endpoint上,我们可以通过以下方式识别:

  • 检查Endpoint的元数据中是否存在ControllerActionDescriptor,并验证该描述器对应的控制器类型是否带有ApiControllerAttribute
  • 这种方式比直接查找ApiControllerAttribute元数据更准确,因为[ApiController]的特性逻辑是通过控制器类型关联的

实战实现

1. 在Middleware中实时判断当前请求的路由

在自定义IMiddleware中,通过HttpContext获取当前匹配的Endpoint,再进行判断:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;

public class CookieValidationMiddleware : IMiddleware
{
    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        var endpoint = context.GetEndpoint();
        if (endpoint != null)
        {
            // 判断当前路由是否属于ApiController
            var controllerActionDescriptor = endpoint.Metadata.GetMetadata<ControllerActionDescriptor>();
            var isApiController = controllerActionDescriptor?.ControllerTypeInfo
                .GetCustomAttribute<ApiControllerAttribute>() != null;

            // 非ApiController请求才验证Cookie
            if (!isApiController)
            {
                if (!context.Request.Cookies.ContainsKey("RequiredCookie"))
                {
                    context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                    await context.Response.WriteAsync("Cookie is required for non-API requests.");
                    return;
                }
            }
        }

        await next(context);
    }
}

2. 预加载所有ApiController路由(启动时缓存)

如果需要提前缓存所有ApiController的路由规则,可以在服务配置时从EndpointDataSource批量提取:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    // 缓存所有ApiController的路由模式
    services.AddSingleton(sp =>
    {
        var endpointDataSource = sp.GetRequiredService<EndpointDataSource>();
        return endpointDataSource.Endpoints
            .Where(endpoint => 
            {
                var descriptor = endpoint.Metadata.GetMetadata<ControllerActionDescriptor>();
                return descriptor?.ControllerTypeInfo.GetCustomAttribute<ApiControllerAttribute>() != null;
            })
            .Select(endpoint => endpoint.RoutePattern?.RawText)
            .Where(pattern => !string.IsNullOrEmpty(pattern))
            .ToList();
    });
}

优势说明

  • 解耦:不再依赖/api这类路径约定,即使ApiController的路由配置变更(比如改为/v2/api),判断逻辑无需修改
  • 准确:直接关联控制器的[ApiController]特性,不会误判非ApiController但路径以/api开头的路由
  • 高效:元数据判断是轻量级操作,不会带来明显性能开销

内容的提问来源于stack exchange,提问作者Kevin Krumwiede

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:45:02