ASP.NET MVC如何匹配指定开头与结尾的路由?
解决ASP.NET MVC路由匹配问题
错误原因
你遇到的异常是因为路由中的捕获所有参数({*url})必须作为路由模板的最后一段,而你的写法把它放在了/check之前,违反了这个规则。
解决方案
方案1:捕获全路径后在Action内处理(推荐)
用{*all}捕获proxy/spell-checker之后的所有内容,然后在Action里验证路径是否以/check结尾,再提取中间的相对资源路径:
[HttpPost, Route("proxy/spell-checker/{*all}")] public async Task<HttpResponseMessage> Check(string all) { // 验证路径格式是否符合要求 if (string.IsNullOrEmpty(all) || !all.EndsWith("/check", StringComparison.OrdinalIgnoreCase)) { // 不符合则返回404,或交给其他路由处理 return new HttpResponseMessage(HttpStatusCode.NotFound); } // 提取proxy/spell-checker与check之间的相对路径 var relativeResourcePath = all.Substring(0, all.Length - "/check".Length); // 执行代理逻辑,比如转发到目标路径 // ... }
这种方式简单直接,不需要额外配置,就能匹配所有以proxy/spell-checker开头、check结尾的URL。
方案2:自定义路由约束(路由层面严格匹配)
如果希望在路由阶段就完成匹配验证,可以自定义路由约束:
- 创建约束类:
public class EndsWithCheckConstraint : IRouteConstraint { public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection) { if (values.TryGetValue(routeKey, out var value) && value is string path) { return path.EndsWith("/check", StringComparison.OrdinalIgnoreCase); } return false; } }
- 在Startup中注册约束:
services.Configure<RouteOptions>(options => { options.ConstraintMap.Add("endsWithCheck", typeof(EndsWithCheckConstraint)); });
- 在Action上应用约束:
[HttpPost, Route("proxy/spell-checker/{path:endsWithCheck}")] public async Task<HttpResponseMessage> Check(string path) { // 提取中间相对路径 var relativeResourcePath = path.Substring(0, path.Length - "/check".Length); // 执行代理逻辑 // ... }
这种方式更严谨,但需要额外的类和配置,适合对路由匹配要求严格的场景。
内容的提问来源于stack exchange,提问作者Denis Kaminsky
相关产品推荐
相关产品推荐

