如何在ASP.NET Core 2.0中获取不含参数的绝对URL路径?
解决ASP.NET Core 2.0 ActionFilter中获取无参数路由路径的问题
我之前做API权限验证时也碰到过这个需求,直接拿请求URL肯定会带参数值,其实我们可以借助ASP.NET Core的路由元数据来精准获取路由模板,比手动解析URL靠谱多了。
核心思路
ASP.NET Core的ActionDescriptor里存着当前Action的路由定义信息,我们可以从ActionExecutingContext中拿到这个对象,然后提取控制器和Action的路由模板,拼接成不带参数的路径。
完整代码示例
public class AuthorizationReqAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext context) { // 转换为ControllerActionDescriptor,适配API控制器场景 var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; if (controllerActionDescriptor == null) { base.OnActionExecuting(context); return; } // 获取控制器的路由前缀(比如api/[controller]) var controllerRouteTemplate = controllerActionDescriptor.ControllerAttributeRouteInfo?.Template; // 获取Action的路由模板(比如get/{id}) var actionRouteTemplate = controllerActionDescriptor.ActionAttributeRouteInfo?.Template; // 拼接完整路由,处理空值和斜杠重复问题 var combinedRoute = string.Empty; if (!string.IsNullOrEmpty(controllerRouteTemplate)) { combinedRoute = controllerRouteTemplate; if (!string.IsNullOrEmpty(actionRouteTemplate)) { combinedRoute = combinedRoute.EndsWith("/") ? $"{combinedRoute}{actionRouteTemplate}" : $"{combinedRoute}/{actionRouteTemplate}"; } } else if (!string.IsNullOrEmpty(actionRouteTemplate)) { combinedRoute = actionRouteTemplate; } // 把路由模板里的[controller]替换成实际控制器名称(比如Values) var finalRoute = combinedRoute.Replace("[controller]", controllerActionDescriptor.ControllerName); // 确保路径以/开头,统一格式 if (!finalRoute.StartsWith("/")) { finalRoute = $"/{finalRoute}"; } // 这里finalRoute就是你要的/api/values/get格式 // 可以用于权限验证、日志记录等业务场景 Console.WriteLine($"当前无参数路由:{finalRoute}"); base.OnActionExecuting(context); } }
为什么不直接解析请求URL?
要是直接从context.HttpContext.Request.Path截取字符串,比如把/api/values/get/1的最后一段去掉,看似简单但隐患很多:
- 遇到多参数路由(比如
/api/values/get/{id}/detail/{detailId}),截取逻辑会变得非常复杂 - 路由参数位置不固定时,很容易截错路径
- 用框架提供的路由元数据才是最准确的方式,毕竟这就是路由定义本身的信息
注意事项
- 类型转换判断:如果你的过滤器还要作用在非API控制器(比如Razor Pages),需要额外处理其他类型的
ActionDescriptor - 空值校验:
ControllerAttributeRouteInfo和ActionAttributeRouteInfo可能为null(比如未标注路由特性的场景),一定要做判断避免空引用异常
内容的提问来源于stack exchange,提问作者sebu
相关产品推荐
相关产品推荐

