在Web Api中find与请求匹配的多个操作

当我尝试使用2个“Get”方法时,我总是收到这个错误

find与请求匹配的多个操作:webapi

我一直在关于堆栈上的其他类似的问题,但我不明白。

我有2个不同的名称,并使用“HttpGet”属性

[HttpGet] public HttpResponseMessage Summary(MyVm vm) { return null; } [HttpGet] public HttpResponseMessage FullDetails() { return null; } 

你的路线图可能是这样的:

 routes.MapHttpRoute( name: "API Default", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional }); 

但为了有相同的http方法多个行动,你需要提供更多的信息通过路线的webapi像这样:

 routes.MapHttpRoute( name: "API Default", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional }); 

请注意,routeTemplate现在包含一个操作。 在这里有更多的信息: http : //www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

更新:

好吧,现在我想我明白你是在这里之后是另一个在这个:

也许你不需要action url参数,并且应该以另一种方式描述你以后的内容。 既然你说的方法是从同一个实体返回数据,那就让这些参数为你做描述吧。

例如,你的两个方法可以变成:

 public HttpResponseMessage Get() { return null; } public HttpResponseMessage Get(MyVm vm) { return null; } 

你在MyVm对象中传递什么样的数据? 如果你能够通过URI传递variables,我会build议去那个路线。 否则,你需要在请求的主体中发送对象,并且在做一个GET的时候,这个对象并不是你的HTTP(尽pipe它只是使用MyVm的[FromBody] infront)。

希望这可以说明,您可以在一个控制器中使用多个GET方法,而无需使用操作名称甚至[HttpGet]属性。

从Web API 2更新。

在WebApiConfig.cs文件中使用这个APIconfiguration:

 public static void Register(HttpConfiguration config) { //// Web API routes config.MapHttpAttributeRoutes(); //Don't miss this config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = System.Web.Http.RouteParameter.Optional } ); } 

你可以像这样路由我们的控制器:

 [Route("api/ControllerName/Summary")] [HttpGet] public HttpResponseMessage Summary(MyVm vm) { rturn null; } [Route("api/ControllerName/FullDetails")] [HttpGet] public HttpResponseMessage FullDetails() { return null; } 

其中ControllerName是您的控制器的名称(没有“控制器”)。 这将允许您使用上面详述的路线获取每个操作。

进一步阅读: http : //www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

在Web API中(默认情况下)方法是基于HTTP方法和路由值组合来select的。

MyVm看起来像一个复杂的对象,由格式化程序从主体中读取,因此在路由数据方面有两个相同的方法(因为它们都没有来自路由的任何参数) – 这使得调度器( IHttpActionSelector )不可能匹配适当的一个。

您需要通过查询string或路由参数来区分它们以解决歧义。

经过大量的searchnetworking,并试图find最适合的路由图的forms,如果发现以下

 config.Routes.MapHttpRoute("DefaultApiWithId", "Api/{controller}/{id}", new { id =RouteParameter.Optional }, new { id = @"\d+" }); config.Routes.MapHttpRoute("DefaultApiWithAction", "Api/{controller}/{action}"); 

这些映射适用于动作名称映射和基本http约定(GET,POST,PUT,DELETE)

您的webmethods可能被parsing为相同的url。 看看下面的链接:

http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

所以,你可能需要将你的方法名添加到你的路由表中。

没有使用行动,选项将是:

  1. 移动其中一个方法到不同的控制器,以免它们发生冲突。

  2. 只使用一个采用param的方法,如果是null,则从代码中调用另一个方法。

我发现,当我有两个Get方法,一个无参数和一个复杂types作为参数,我得到了同样的错误。 我通过添加一个types为int的虚拟参数(名为Id)作为我的第一个参数,然后是我的复杂types参数来解决此问题。 然后,我将复杂types参数添加到路由模板。 以下为我工作。

首先得到:

 public IEnumerable<SearchItem> Get() { ... } 

第二个得到:

 public IEnumerable<SearchItem> Get(int id, [FromUri] List<string> layers) { ... } 

WebApiConfig:

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

请检查你有两个具有不同名称和相同参数的方法。

如果是这样,请删除任何方法,并尝试。

我偶然发现了这个问题,同时试图增加我的WebAPI控制器的额外的行动。

假设你会有

 public IEnumerable<string> Get() { return this.Repository.GetAll(); } [HttpGet] public void ReSeed() { // Your custom action here } 

现在有两种方法可以满足触发TS所描述问题的/ api / controller的请求。

我不想为我的附加操作添加“虚拟”参数,所以我查看了默认操作,并提出:

 [ActionName("builtin")] public IEnumerable<string> Get() { return this.Repository.GetAll(); } 

对于第一种方法与“双重”路由绑定的组合:

 config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { action = "builtin", id = RouteParameter.Optional }, constraints: new { id = @"\d+" }); config.Routes.MapHttpRoute( name: "CustomActionApi", routeTemplate: "api/{controller}/{action}"); 

请注意,即使在第一个路由模板中没有“action”参数,显然仍然可以configuration默认操作,以允许我们将“正常”WebAPI调用的路由和对额外操作的调用分开。

这可能是由于使用MVC控制器而不是Web API控制器。 检查Web API控制器中的命名空间应如下所示

 using System.Net; using System.Net.Http; using System.Web.Http; 

如果命名空间如下所示,则会在web api控制器方法调用中出现以上错误

 using System.Web; using System.Web.Mvc; 

我知道这是一个老问题,但有时候,当你使用像AngularJS这样的服务资源来连接到WebAPI时,确保你使用的是正确的路由,否则这个错误会发生。

确保你没有用[HttpPost / Put / Get / Delete]属性来修饰默认的GET | PUT | POST | DELETE动作的Controller方法。 我已经添加了这个属性到我的香草邮政控制器的行动,并造成了404。

希望这可以帮助某个人,因为这会让人感到非常沮丧,并使进度停止。