这些 Web API 路由的顺序有什么问题
What is wrong with the order of these Web API routes
所以我在 WebApiConfig.cs
文件中添加了一些路由,我可以接到第一个和第二个上班电话,但不能接到 GADailyAPI 上班电话。我得到一个 404。当第一次编写代码时,前两行路由位于底部,它们会抛出 404。我尝试更改顺序,但我无法让它们全部工作。有任何想法吗? 注意:这不是我的代码,所以如果可以的话,我不想修改太多 API 代码。如果我能弄清楚路由顺序并修复它,那将是最好的解决方案
config.Routes.MapHttpRoute(
name: "GAMonthlyApiNetworkStats",
routeTemplate: "api/{controller}/{action}/{Year}/{Month}",
defaults: new { controller = "GAMonthlyAPI", action = "NetworkStats" }
);
config.Routes.MapHttpRoute(
name: "GAMonthlyApiAllStats",
routeTemplate: "api/{controller}/{action}/{Year}/{Month}",
defaults: new { controller = "GAMonthlyAPI", action = "AllStats", }
);
config.Routes.MapHttpRoute(
name: "GADailyApiNetworkStats",
routeTemplate: "api/{controller}/{action}/{StartDate}/{EndDate}",
defaults: new { controller = "GADailyAPI", action = "NetworkStats" }
);
config.Routes.MapHttpRoute(
name: "GADailyApiAllStats",
routeTemplate: "api/{controller}/{action}/{StartDate}/{EndDate}",
defaults: new { controller = "GADailyAPI", action = "AllStats" }
);
config.Routes.MapHttpRoute(
name: "GAMonthlyApiGroupStats",
routeTemplate: "api/{controller}/{action}/{Year}/{Month}/{GroupID}",
defaults: new { controller = "GAMonthlyAPI", action = "GroupStats" }
);
config.Routes.MapHttpRoute(
name: "GAMonthlyApiSiteStats",
routeTemplate: "api/{controller}/{action}/{Year}/{Month}/{SiteID}",
defaults: new { controller = "GAMonthlyAPI", action = "SiteStats" }
);
config.Routes.MapHttpRoute(
name: "GADailyApiGroupStats",
routeTemplate: "api/{controller}/{action}/{StartDate}/{EndDate}/{GroupID}",
defaults: new { controller = "GADailyAPI", action = "GroupStats" }
);
config.Routes.MapHttpRoute(
name: "GADailyApiSiteStats",
routeTemplate: "api/{controller}/{action}/{StartDate}/{EndDate}/{SiteID}",
defaults: new { controller = "GADailyAPI", action = "SiteStats" }
);
顺序没有错,因为第一场比赛总是赢,所以无论您以什么顺序放置一条包含 5 个以 /api
开头的路段的路线第一条路线将到达。这是因为像 {action}
这样的占位符实际上可以是 任何字符串 。所以你基本上是在说:
Match if the url is: /api/<anything>/<anything>/<anything>/<anything>
所有前 4 条路线和:
Match if the url is: /api/<anything>/<anything>/<anything>/<anything>/<anything>
在休息。
要解决此问题,您需要以某种方式限制路由,以便路由框架在不匹配时跳过第一条路由,然后继续下一条路由并尝试匹配该路由。
config.Routes.MapHttpRoute(
name: "GAMonthlyApiNetworkStats",
routeTemplate: "api/{controller}/NetworkStats/{Year}/{Month}",
defaults: new { controller = "GAMonthlyAPI", action = "NetworkStats" }
);
config.Routes.MapHttpRoute(
name: "GAMonthlyApiAllStats",
routeTemplate: "api/{controller}/AllStats/{Year}/{Month}",
defaults: new { controller = "GAMonthlyAPI", action = "AllStats", }
);
现在 URL 如 /api/GAMonthlyAPI/AllStats/2012/09
将跳过第一条路线,因为 AllStats
段与第三段不匹配,并且将匹配第二条路线,因为第三段是与传递的值相同。
参考:
尝试添加 httpMethod 和约束,可能会有帮助:
routes.MapHttpRoute(
name: "ApiPut",
routeTemplate: "api/{controller}/{id}",
defaults: new { action = "Put" },
constraints: new { httpMethod = new HttpMethodConstraint("Put") }
);
所以我在 WebApiConfig.cs
文件中添加了一些路由,我可以接到第一个和第二个上班电话,但不能接到 GADailyAPI 上班电话。我得到一个 404。当第一次编写代码时,前两行路由位于底部,它们会抛出 404。我尝试更改顺序,但我无法让它们全部工作。有任何想法吗? 注意:这不是我的代码,所以如果可以的话,我不想修改太多 API 代码。如果我能弄清楚路由顺序并修复它,那将是最好的解决方案
config.Routes.MapHttpRoute(
name: "GAMonthlyApiNetworkStats",
routeTemplate: "api/{controller}/{action}/{Year}/{Month}",
defaults: new { controller = "GAMonthlyAPI", action = "NetworkStats" }
);
config.Routes.MapHttpRoute(
name: "GAMonthlyApiAllStats",
routeTemplate: "api/{controller}/{action}/{Year}/{Month}",
defaults: new { controller = "GAMonthlyAPI", action = "AllStats", }
);
config.Routes.MapHttpRoute(
name: "GADailyApiNetworkStats",
routeTemplate: "api/{controller}/{action}/{StartDate}/{EndDate}",
defaults: new { controller = "GADailyAPI", action = "NetworkStats" }
);
config.Routes.MapHttpRoute(
name: "GADailyApiAllStats",
routeTemplate: "api/{controller}/{action}/{StartDate}/{EndDate}",
defaults: new { controller = "GADailyAPI", action = "AllStats" }
);
config.Routes.MapHttpRoute(
name: "GAMonthlyApiGroupStats",
routeTemplate: "api/{controller}/{action}/{Year}/{Month}/{GroupID}",
defaults: new { controller = "GAMonthlyAPI", action = "GroupStats" }
);
config.Routes.MapHttpRoute(
name: "GAMonthlyApiSiteStats",
routeTemplate: "api/{controller}/{action}/{Year}/{Month}/{SiteID}",
defaults: new { controller = "GAMonthlyAPI", action = "SiteStats" }
);
config.Routes.MapHttpRoute(
name: "GADailyApiGroupStats",
routeTemplate: "api/{controller}/{action}/{StartDate}/{EndDate}/{GroupID}",
defaults: new { controller = "GADailyAPI", action = "GroupStats" }
);
config.Routes.MapHttpRoute(
name: "GADailyApiSiteStats",
routeTemplate: "api/{controller}/{action}/{StartDate}/{EndDate}/{SiteID}",
defaults: new { controller = "GADailyAPI", action = "SiteStats" }
);
顺序没有错,因为第一场比赛总是赢,所以无论您以什么顺序放置一条包含 5 个以 /api
开头的路段的路线第一条路线将到达。这是因为像 {action}
这样的占位符实际上可以是 任何字符串 。所以你基本上是在说:
Match if the url is: /api/<anything>/<anything>/<anything>/<anything>
所有前 4 条路线和:
Match if the url is: /api/<anything>/<anything>/<anything>/<anything>/<anything>
在休息。
要解决此问题,您需要以某种方式限制路由,以便路由框架在不匹配时跳过第一条路由,然后继续下一条路由并尝试匹配该路由。
config.Routes.MapHttpRoute(
name: "GAMonthlyApiNetworkStats",
routeTemplate: "api/{controller}/NetworkStats/{Year}/{Month}",
defaults: new { controller = "GAMonthlyAPI", action = "NetworkStats" }
);
config.Routes.MapHttpRoute(
name: "GAMonthlyApiAllStats",
routeTemplate: "api/{controller}/AllStats/{Year}/{Month}",
defaults: new { controller = "GAMonthlyAPI", action = "AllStats", }
);
现在 URL 如 /api/GAMonthlyAPI/AllStats/2012/09
将跳过第一条路线,因为 AllStats
段与第三段不匹配,并且将匹配第二条路线,因为第三段是与传递的值相同。
参考:
尝试添加 httpMethod 和约束,可能会有帮助:
routes.MapHttpRoute(
name: "ApiPut",
routeTemplate: "api/{controller}/{id}",
defaults: new { action = "Put" },
constraints: new { httpMethod = new HttpMethodConstraint("Put") }
);