【问题标题】:What is wrong with the order of these Web API routes这些 Web API 路由的顺序有什么问题
【发布时间】:2018-07-13 09:53:16
【问题描述】:

所以我在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" }
        );

【问题讨论】:

    标签: c# asp.net-web-api routes asp.net-web-api-routing


    【解决方案1】:

    顺序没有什么问题,因为第一场比赛总是获胜,所以无论你放置一个以/api开头的5段路线的顺序如何,都只会到达第一条路线。这是因为像{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", }
        );
    

    现在像 /api/GAMonthlyAPI/AllStats/2012/09 这样的 URL 将跳过第一个路由,因为 AllStats 段与第三个段不匹配,并且将匹配第二个路由,因为第三个段与传递的值相同。

    参考:Why map special routes first before common routes in asp.net mvc?

    【讨论】:

    • 谢谢,这是我正在寻找的解释。
    【解决方案2】:

    尝试添加 httpMethod 和约束,它可能会有所帮助:

    routes.MapHttpRoute(
    name: "ApiPut", 
    routeTemplate: "api/{controller}/{id}",
    defaults: new { action = "Put" }, 
    constraints: new { httpMethod = new HttpMethodConstraint("Put") }
    );
    

    【讨论】:

      猜你喜欢
      • 2017-07-28
      • 1970-01-01
      • 1970-01-01
      • 2014-11-27
      • 2013-08-30
      • 2017-03-26
      • 2013-09-23
      相关资源
      最近更新 更多