【问题标题】:'Multiple actions were found' error“发现多个操作”错误
【发布时间】:2013-03-20 05:45:12
【问题描述】:

我为我的 web api 服务设置了以下默认路由...

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

config.Routes.MapHttpRoute(
    name: "DefaultPost",
    routeTemplate: "api/{controller}",
    defaults: new { action = "Post" },
    constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Post) }
    );

config.Routes.MapHttpRoute(
    name: "DefaultGetWithId",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { action = "Get" },
    constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) }
    );

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

config.Routes.MapHttpRoute(
    name: "DefaultDeleteWithId",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { action = "Delete" },
    constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Delete) }
    );

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

我在“UsersController”下有以下服务:

public UserDto Get(string id){}

[HttpGet]
public UserDto ByEmail(string email)

[HttpGet]
public bool IsEmailUnique(string email)

问题是,当我尝试点击这三个服务中的任何一个时,我收到了“发现多个操作”错误。请求应该从所有路由中选择最后一个路由并执行请求。

如果我要执行'/api/users/byemail?email=blah@blah.com',不应该知道'ByEmail'是动作并且使用方法和动作,匹配正确的方法吗?我想我错过了什么。

【问题讨论】:

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


    【解决方案1】:

    您似乎已将 BeEmail 和 IsEmailUnique 方法映射到 GET 操作,这导致找到多个操作。

    由于您已经为命名操作(DefaultControllerWithAction)设置了路由模板,您可以删除 [HttpGet] 属性。

    在此之后,路由模板“DefaultControllerWithAction”应该整理出“/api/users/byemail”就好了

    编辑: 在同一个 ApiController 中混合传统路由和基于动词的路由似乎存在问题。 这已记录在 here on codeplex 并且有一篇博客文章声称已经解决了这个问题(尚未测试): http://blog.appliedis.com/2013/03/25/web-api-mixing-traditional-verb-based-routing/

    编辑2:
    刚刚对此进行了测试,Kip Streihorst 的解决方案适合您的情况。

    第 1 步:硬编码默认值,而不是指定该操作是可选的。
    第 2 步:使用硬编码的默认操作名称装饰“基于动词的控制器”

    对于您的获取请求,这将是:

    config.Routes.MapHttpRoute( 名称:“DefaultControllerWithAction”, routeTemplate: "api/{controller}/{action}", 默认值:新 { action = "DefaultAction } ); config.Routes.MapHttpRoute( 名称:“DefaultGetWithId”, routeTemplate: "api/{controller}/{id}", 默认值:新 { action = "Get" }, 约束:新 { httpMethod = 新 HttpMethodConstraint(HttpMethod.Get) } ); config.Routes.MapHttpRoute( name: "DefaultControllerWithIdAndAction", routeTemplate: "api/{controller}/{id}/{action}", 默认值:新 { action = "DefaultAction" } );

    [ActionName("DefaultAction")] 公共 UserDto 获取(字符串 id){} [HttpGet] 公共 UserDto ByEmail(字符串电子邮件) [HttpGet] 公共布尔 IsEmailUnique(字符串电子邮件)

    【讨论】:

    • 我认为需要“HttpGet”来让 api 知道该服务只需要一个 Get 请求。否则,默认为 POST。
    • Doh...是的,我的错,对不起那个错误。在同一个 ApiController 中混合传统路由和基于动词的路由似乎存在问题。这记录在这里:aspnetwebstack.codeplex.com/workitem/184,并且有一篇博客文章声称已经解决了这个问题:blog.appliedis.com/2013/03/25/… 希望这比我的错误答案更有帮助..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 2014-09-28
    相关资源
    最近更新 更多