1

我有一个带有两种 POST 方法的控制器:

[WebInvoke(Method = "POST", UriTemplate = "/api/controller/action1")]
[ActionName("action1")]
public HttpResponseMessage MethodA(string s1, string s2);

[WebInvoke(Method = "POST", UriTemplate = "/api/controller/action2")]
[ActionName("action2")]
public HttpResponseMessage MethodB(string s1, InternalClass c);

我从测试工具中调用它。当我尝试POST使用MethodBURLhttp://localhost/api/controller?s1=<string>并传入cPOST 正文时,该消息表明它正在尝试调用 MethodA(我有一个验证过滤器,指示“s1 和 s2 是必填字段”)。

POST当我将操作添加到URL 并尝试MethodB使用http://localhost/api/controller/action2?s1=<string>,传入c正文时,我得到了 404。

我修改了我RouteConfig的使用这些路线:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapHttpRoute(
  name: "Name1",
  routeTemplate: "api/{controller}"
);

routes.MapHttpRoute(
  name: "Name2",
  routeTemplate: "api/{controller}/{id}",
  defaults: null,
  constraints: new { id = @"^\d+$" } // Only integers 
);

routes.MapHttpRoute(
  name: "Name3",
  routeTemplate: "api/{controller}/{action}"
);

routes.MapRoute(
  name: "Default",
  url: "api/{controller}/{action}/{id}",
  defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
);

正如这个问题所示。

我究竟做错了什么?

4

1 回答 1

2

当我尝试使用 URL POST 到 MethodB 并在http://localhost/api/controller?s1=<string>POST 的正文中传递 c 时,该消息表明它正在尝试调用 MethodA(我有一个验证过滤器,指示“s1 和 s2 是必填字段”)。

听起来您正试图依靠重载来消除路线的歧义——MVC 不能这样工作。您必须确保您的路线被定义为唯一的,只有一条路线POSTGET每条路线。

在这种情况下,默认的操作方法/api/controllerMethodA,它试图强制对象C进入 的第二个参数MethodA

如果您希望默认转到MethodB,则必须更新您的路线。但是,听起来您希望它是动态的并根据发布的参数找出路线,但它不是那样工作的。

另外,这条路线:

routes.MapRoute(
  name: "Default",
  url: "api/{controller}/{action}/{id}",
  defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
);

看起来错了,因为它指向Default控制器,Index动作方法,你没有在你的代码中列出。所以要去api/controller会尽量去Default.Index

最后,考虑路线的顺序。当 MVC 管道评估您的路由时,它将匹配第一个可能的路由。在您的情况下,顶部有更通用的路线,底部有更具体的路线。您需要重新排序这些,将更具体的路线放在顶部。这篇文章谈到了这一点。

于 2013-11-08T20:37:37.377 回答