部分匹配是否会破坏Web Api HTTP路由扫描?

时间:2013-12-03 16:51:02

标签: asp.net-mvc asp.net-mvc-4 asp.net-web-api

我的印象是,在MVC4中,WebApi会尝试匹配第一条规则,如果它不成功,那么它将继续下一条规则。但在我的应用程序中由于某种原因,第一条规则部分匹配导致MVC4不尝试第二条规则。这是一个例子:

    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.Routes.MapHttpRoute(
            name: "ApiByAction",
            routeTemplate: "api/{controller}/{action}",
            defaults: new { action = "Get" }
        );
    }


    public class MyController: ApiController
    {
        public Boolean GetMyAction(string Param1, string Param2)
        {
            return true;
        }
    }

上面的规则是默认规则,我使用此网址/api/MyController/MyAction?Param1=xxx&Param2=yyy进行了GET调用。这与第一个规则匹配,因为id是可选的,参数加请求方法(GET)也与控制器动作相同。但是,如果我翻开这两条规则,我就不再匹配了。

我收到错误No action was found on the controller MyController that matches the name "MyAction"。在控制器中,我的操作名称为GetMyAction,因此它无法匹配。但是为什么它不会进入我知道会匹配的下一个规则呢?

在这个问题的另一面,我确实有其他控制器具有多个GET动作而没有参数。因此,为了不在DefaultApi规则上获得多重匹配错误,我需要先按名称进行匹配。

2 个答案:

答案 0 :(得分:0)

您应该指定最通用路由的最具体路由,就像我们对try/catch块中的异常一样。

public static void Register(HttpConfiguration config)
{

     config.Routes.MapHttpRoute(
         name: "ApiByAction",
         routeTemplate: "api/{controller}/{action}",
         defaults: new { action = "Get" }
     );

     config.Routes.MapHttpRoute(
         name: "DefaultApi",
         routeTemplate: "api/{controller}/MyAction",
         defaults: new { action = "MyAction" }
     );

     config.Routes.MapHttpRoute(
         name: "DefaultApi",
         routeTemplate: "api/{controller}/{id}",
         defaults: new { id = RouteParameter.Optional }
     );

}

有了这个,asp.net web api将找到第一个,并使其工作正常,如果没有,将找到使用第二个模式。

答案 1 :(得分:0)

经过一番研究后,我找到了routing and action selection web page。该页面提供了以下用于路由的阶段:

  1. 将URI与路径模板匹配。
  2. 选择控制器。
  3. 选择一项行动。
  4. 对我的口味并不是绝对明确的。但我知道匹配阶段仅适用于路由模板字符串。查找匹配的控制器和操作不是查找要使用的实际路由规则的一部分。如果没有找到动作/控制器,则可以查找下一个匹配的路由字符串。但这不是它的实施方式。如果我们将规则视为一个整体,部分匹配将通过设计中断匹配过程。