在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
所以,你可能需要将你的方法名添加到你的路由表中。
没有使用行动,选项将是:
-
移动其中一个方法到不同的控制器,以免它们发生冲突。
-
只使用一个采用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。
希望这可以帮助某个人,因为这会让人感到非常沮丧,并使进度停止。