ASP.NET API路由:将自定义客户端URL映射至现有API
可行解决方案
方案一:使用URL重写中间件
这是最直接且易维护的方式,ASP.NET Core的URL重写中间件可以轻松实现URL映射规则。
在Program.cs中添加以下配置:
var builder = WebApplication.CreateBuilder(args); // 注册服务 builder.Services.AddControllers(); var app = builder.Build(); // 配置URL重写规则 var rewriteOptions = new RewriteOptions() .AddRewrite(@"^(\w+)/(\w+)/(\d+)$", "eapi/1.0/Diff-$1/$2/$3", skipRemainingRules: true); app.UseRewriter(rewriteOptions); app.MapControllers(); app.Run();
- 正则说明:
^(\w+)/(\w+)/(\d+)$匹配客户端请求的/controller/action/id格式(其中controller和action为字母数字组合,id为数字,若id有其他格式可调整正则) - 替换规则:
eapi/1.0/Diff-$1/$2/$3把捕获到的controller替换为Diff-<controller>,并拼接前缀路径
如果你的controller名称可能包含非字母数字字符,可将正则调整为^([^/]+)/([^/]+)/([^/]+)$,匹配任意非斜杠的分段。
方案二:修正DynamicRouteValueTransformer用法
如果你坚持使用路由值转换的方式,可能之前的配置有误,以下是正确的实现步骤:
- 实现自定义的
DynamicRouteValueTransformer:
public class CustomRouteTransformer : DynamicRouteValueTransformer { public override ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values) { if (values.TryGetValue("controller", out var controller) && controller is string controllerName) { // 替换controller名称为Diff-<controller> values["controller"] = $"Diff-{controllerName}"; // 直接修改请求路径,指向内部API地址 httpContext.Request.Path = $"/eapi/1.0/{values["controller"]}/{values["action"]}/{values["id"]}"; } return new ValueTask<RouteValueDictionary>(values); } }
- 在路由中注册并使用该转换器:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); // 注册自定义转换器 builder.Services.AddSingleton<DynamicRouteValueTransformer, CustomRouteTransformer>(); var app = builder.Build(); app.MapDynamicControllerRoute<CustomRouteTransformer>("{controller}/{action}/{id}"); app.Run();
注意:这种方式需要确保你的现有API控制器名称是Diff-Controller格式(比如Diff-HomeController),否则路由无法匹配到对应的控制器。
方案三:属性路由映射
如果你的控制器数量不多,也可以直接在现有API控制器上添加额外的属性路由,直接对外暴露所需的URL:
[ApiController] [Route("eapi/1.0/[controller]")] // 添加对外的路由规则 [Route("[controller]")] public class Diff-HomeController : ControllerBase { [HttpGet("{action}/{id}")] public IActionResult SomeAction(int id) { // 现有业务逻辑 return Ok(); } }
这种方式无需额外中间件,直接通过属性路由同时支持两种URL访问。
内容的提问来源于stack exchange,提问作者Amol
相关产品推荐
相关产品推荐

