我的印象是,在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
规则上获得多重匹配错误,我需要先按名称进行匹配。
答案 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。该页面提供了以下用于路由的阶段:
对我的口味并不是绝对明确的。但我知道匹配阶段仅适用于路由模板字符串。查找匹配的控制器和操作不是查找要使用的实际路由规则的一部分。如果没有找到动作/控制器,则可以查找下一个匹配的路由字符串。但这不是它的实施方式。如果我们将规则视为一个整体,部分匹配将通过设计中断匹配过程。