找到了与Web Api中的请求匹配的多个操作

时间:2013-01-26 05:27:52

标签: c# .net asp.net-web-api asp.net-web-api-routing

当我尝试使用2个“获取”方法时,我一直收到此错误

  

找到符合请求的多项操作:webapi

我一直在寻找有关此问题的其他类似问题,但我不明白。

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

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

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

17 个答案:

答案 0 :(得分:436)

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

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

<强>更新

好吧,现在我觉得我明白你的意思是另一种看法:

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

例如,您可以将两种方法转换为:

public HttpResponseMessage Get()
{
    return null;
}

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

您在MyVm对象中传递了哪些数据?如果你能够通过URI传递变量,我建议去那条路线。否则,您需要在请求正文中发送对象,并且在执行GET时不是非常HTTP(它可以工作,只需使用MyVm前面的[FromBody])。

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

答案 1 :(得分:59)

从Web API 2开始更新。

在WebApiConfig.cs文件中使用此API配置:

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

答案 2 :(得分:15)

在Web API中(默认情况下),基于HTTP方法和路由值的组合选择方法

MyVm看起来像一个复杂的对象,由格式化程序从正文中读取,因此您在路径数据方面有两个相同的方法(因为它们都没有路由中的任何参数) - 这使得它无法进行调度员(IHttpActionSelector)匹配适当的调度员。

您需要通过querystring或route参数区分它们以解决歧义。

答案 3 :(得分:13)

经过大量搜索网络并试图找到最适合路由地图的表格 如果找到以下

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)

答案 4 :(得分:5)

不使用操作,选项将是:

  1. 将其中一个方法移动到另一个控制器,这样它们就不会发生冲突。

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

答案 5 :(得分:5)

您的网络方法可能会被解析为同一个网址。看看以下链接: -

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

因此,您可能需要将您的方法名称添加到路由表中。

答案 6 :(得分:4)

这个解决方案对我有用。

请先将Route2放在WebApiConfig中。还要在每个方法之前添加HttpGet和HttpPost,并在URL中包含控制器名称和方法名称。

WebApiConfig =&gt;

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

Controller =&gt;

public class ValuesController : ApiController
{

    [HttpPost]
    public string GetCustomer([FromBody] RequestModel req)
    {
        return "Customer";
    }

    [HttpPost]
    public string GetCustomerList([FromBody] RequestModel req)
    {
        return "Customer List";
    }
}

Url =&gt;

http://localhost:7050/api/Values/GetCustomer

http://localhost:7050/api/Values/GetCustomerList

答案 7 :(得分:3)

由于使用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;

答案 8 :(得分:3)

我发现当我有两个Get方法,一个无参数和一个复杂类型作为参数时,我得到了相同的错误。我通过添加一个名为Id的int类型的伪参数作为我的第一个参数,然后是我的复杂类型参数来解决这个问题。然后我将复杂类型参数添加到路由模板中。以下对我有用。

首先得到:

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 }
);

答案 9 :(得分:2)

在尝试使用额外操作扩充我的WebAPI控制器时,我偶然发现了这个问题。

假设你有

public IEnumerable<string> Get()
{
    return this.Repository.GetAll();
}

[HttpGet]
public void ReSeed()
{
    // Your custom action here
}

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

我不想在我的其他操作中添加“虚拟”参数,因此我查看了默认操作并提出了:

[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”参数,您仍然可以配置默认操作,允许我们将“正常”WebAPI调用的路由与对额外操作的调用分开。

答案 10 :(得分:2)

请检查您有两种方法,它们具有不同的名称和相同的参数。

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

答案 11 :(得分:2)

这是所有知道一切正确并已检查50次的人的答案 .....

确保您没有反复查看RouteConfig.cs

您要编辑的文件名为WebApiConfig.cs

另外,它可能看起来应该像这样:

using System.Web.Http;

namespace My.Epic.Website
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
          config.MapHttpAttributeRoutes();

          // api/Country/WithStates
          config.Routes.MapHttpRoute(
            name: "ControllerAndActionOnly",
            routeTemplate: "api/{controller}/{action}",
            defaults: new { },
            constraints: new { action = @"^[a-zA-Z]+([\s][a-zA-Z]+)*$" });

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

我本可以节省大约3个小时。

答案 12 :(得分:0)

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

答案 13 :(得分:0)

确保不使用[HttpPost / Put / Get / Delete]属性为默认的GET | PUT | POST | DELETE操作修饰Controller方法。我已将此属性添加到我的vanilla Post控制器操作中,它导致了404.

希望这可以帮助某人,因为它可能非常令人沮丧,并使进展停止。

答案 14 :(得分:0)

例如=> TestController

        [HttpGet]
        public string TestMethod(int arg0)
        {
            return "";
        }

        [HttpGet]
        public string TestMethod2(string arg0)
        {
            return "";
        }

        [HttpGet]
        public string TestMethod3(int arg0,string arg1)
        {
            return "";
        }

如果您只能更改WebApiConfig.cs文件。

 config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/",
                defaults: null
            );

就这样:)

结果: enter image description here

答案 15 :(得分:0)

您是否尝试过:

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

[HttpGet("FullDetails")]
public HttpResponseMessage FullDetails()
{
    return null;
}

答案 16 :(得分:0)

您可以将[Route("api/[controller]/[action]")]添加到控制器类。

[Route("api/[controller]/[action]")]
[ApiController]
public class MySuperController : ControllerBase
{
 ...
}