具有多个动作的控制器 - 称为错误动作

时间:2013-11-08 19:09:51

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

我有一个带有两种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 MethodBhttp://localhost/api/controller?s1=<string>,在POST正文中传递c时,该消息表明它正在尝试调用MethodA(我有验证过滤器,指示“s1和s2是必填字段”。)

当我将操作添加到网址并尝试使用POST MethodBhttp://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 }
);

this question中所示。

我做错了什么?

1 个答案:

答案 0 :(得分:2)

  

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

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

在这种情况下,/api/controller的默认操作方法是MethodA,并且它正在尝试将对象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管道评估您的路线时,它将匹配第一条可能的路线。在您的情况下,您在顶部有更通用的路由,底部有更具体的路由。您需要重新排序这些,将更具体的路线放在顶部。 This article谈到这一点。