如何判断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
相关产品推荐
相关产品推荐

