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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:39:47