.NET 6 Web API如何获取控制器API操作方法的路由/路由模板
.NET 6 下获取指定控制器方法路由生成回调URL实现方案
不需要手动遍历路由表维护路由条目,.NET 6 内置的LinkGenerator服务原生支持按控制器、操作方法名生成对应路由路径,自动处理路由前缀、模板参数、约束等逻辑,同时支持跨控制器生成路由,完全匹配需求。
核心实现
LinkGenerator是框架默认自动注册的服务,可通过构造函数注入,也可直接通过HttpContext.GetLinkGenerator()获取,无需额外注册服务。
以下是改造后的可直接运行的代码:
[ApiController] [Route("api/[controller]")] public class MyController : ControllerBase { private readonly LinkGenerator _linkGenerator; // 构造函数注入LinkGenerator public MyController(ILogger<MyController> logger, LinkGenerator linkGenerator) { _linkGenerator = linkGenerator; } [HttpPost("operationVerb1/{what}")] public string DoSomething(string what) { string? callbackPath = null; if (what == "looks like for verb2 ...") { // 生成同控制器DoSomething2方法的路由路径 // 跨控制器场景下,将controller参数替换为目标控制器类名去掉"Controller"后缀即可,例如OtherController对应传"Other" callbackPath = _linkGenerator.GetPathByAction( httpContext: HttpContext, action: nameof(DoSomething2), controller: nameof(MyController).Replace("Controller", string.Empty) ); } else if (what == "looks like something else ...") { callbackPath = _linkGenerator.GetPathByAction( httpContext: HttpContext, action: nameof(DoSomething3), controller: nameof(MyController).Replace("Controller", string.Empty) ); } if (string.IsNullOrWhiteSpace(callbackPath)) { return "No valid callback route found"; } // 拼接完整回调地址,自动适配当前请求的协议、域名/端口,无需硬编码https var callbackUrl = new Uri($"{Request.Scheme}://{Request.Host}{callbackPath}"); return $"Ok, we're doing something, but in half an hour you must call ...{callbackUrl}"; } [HttpGet("operationVerb2")] public string DoSomething2() { return "Operation 2 executed"; } [HttpGet("operationVerb3")] public string DoSomething3() { return "Operation 3 executed"; } }
特殊场景处理
- 路由带路径参数:如果目标方法的路由模板包含参数(例如
[HttpGet("operationVerb4/{id}")]),传入路由值参数即可自动填充模板:
callbackPath = _linkGenerator.GetPathByAction( HttpContext, action: "DoSomething4", controller: "Other", values: new { id = 10086 } // 自动把{id}替换为10086,生成路径类似/api/Other/operationVerb4/10086 );
- 需要枚举某个操作方法绑定的所有路由:如果一个方法标记了多个路由特性(例如同时兼容新旧版本路由),可注入
IActionDescriptorCollectionProvider服务筛选目标方法的所有路由配置:
// 构造函数注入IActionDescriptorCollectionProvider _actionProvider var targetRoutes = _actionProvider.ActionDescriptors.Items .OfType<ControllerActionDescriptor>() .Where(ad => ad.ControllerName == "My" && ad.ActionName == nameof(DoSomething2) ) .ToList(); // 每个ControllerActionDescriptor的AttributeRouteInfo.Template属性存储了对应路由模板
注意事项
- 传入的控制器名不要带
Controller后缀,用nameof(控制器类名).Replace("Controller", "")的写法可以避免硬拼写错,后续重命名控制器时也不会漏改 - 不要手动硬拼接路由字符串,后续修改控制器、方法上的路由特性时,
LinkGenerator会自动读取最新配置,不会出现硬拼地址和实际路由不匹配的问题 - 拼接完整URL时优先取
Request.Scheme,不要硬编码https://,避免本地http调试环境下生成错误地址
内容的提问来源于stack exchange,提问作者user1470240
相关产品推荐
相关产品推荐

