C# 在Web Api中找到多个与请求匹配的操作

C# 在Web Api中找到多个与请求匹配的操作,c#,.net,asp.net-web-api,asp.net-web-api-routing,C#,.net,Asp.net Web Api,Asp.net Web Api Routing,当我尝试使用2个“Get”方法时,总是会出现此错误 找到多个与请求匹配的操作:webapi 我一直在看其他类似的问题,但我不明白 我有两个不同的名称,并使用“HttpGet”属性 [HttpGet] public HttpResponseMessage Summary(MyVm vm) { return null; } [HttpGet] public HttpResponseMessage FullDetails() { return null; } 您的webmethod

当我尝试使用2个“Get”方法时,总是会出现此错误

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

我一直在看其他类似的问题,但我不明白

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

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

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

您的webmethods可能正在解析为同一url。请查看以下链接:-


因此,您可能需要将methodname添加到路由表中。

您的路由图可能如下所示:

routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
[Route("api/ControllerName/Summary")]
[HttpGet]
public HttpResponseMessage Summary(MyVm vm)
{
    return null;
}

[Route("api/ControllerName/FullDetails")]
[HttpGet]
public HttpResponseMessage FullDetails()
{
    return null;
}
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 }
          );
    }
    }
}
但是,为了使用相同的http方法执行多个操作,您需要通过以下路径向webapi提供更多信息:

routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional });
请注意,routeTemplate现在包含一个操作。更多信息请点击此处:

更新:

好吧,现在我想我明白你在想什么了,这是另一个观点:

也许您不需要actionurl参数,而应该用另一种方式描述您所关注的内容。既然您说这些方法是从同一个实体返回数据,那么就让这些参数为您做描述吧

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

public HttpResponseMessage Get()
{
    return null;
}

public HttpResponseMessage Get(MyVm vm)
{
    return null;
}
在MyVm对象中传递的是什么类型的数据?如果您能够通过URI传递变量,我建议您这样做。否则,您将需要在请求体中发送对象,而在执行GET时,这并不是非常适合您(尽管它可以工作,但只需在MyVm前面使用[FromBody])


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

如果不使用操作,选项将是:

  • 将其中一个方法移动到其他控制器,以便它们不会发生冲突

  • 只使用一个获取param的方法,如果为null,则从代码中调用另一个方法

  • 在WebAPI中(默认情况下),根据HTTP方法和路由值的组合选择方法

    MyVm
    看起来像一个复杂的对象,由格式化程序从主体中读取,因此在路由数据方面有两个相同的方法(因为它们都没有路由中的任何参数),这使得dispatcher(
    IHttpActionSelector
    )无法匹配相应的方法


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

    请检查您有两种名称不同、参数相同的方法


    如果是这样,请删除其中任何一种方法,并在大量搜索web并试图找到最适合路由图的表单后重试。

    如果您发现以下内容

    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)

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

    首先获得:

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

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

    假设你会

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

    请注意,即使第一个路由模板中没有“action”参数,显然您仍然可以配置默认操作,允许我们将“普通”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;
    

    从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 }
        );
    }
    
    您可以按如下方式路由控制器:

    routes.MapHttpRoute(
    name: "API Default",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional });
    
    [Route("api/ControllerName/Summary")]
    [HttpGet]
    public HttpResponseMessage Summary(MyVm vm)
    {
        return null;
    }
    
    [Route("api/ControllerName/FullDetails")]
    [HttpGet]
    public HttpResponseMessage FullDetails()
    {
        return null;
    }
    
    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 }
              );
        }
        }
    }
    
    其中ControllerName是控制器的名称(不带“控制器”)。这将允许您使用上面详述的路线获取每个操作


    进一步阅读:

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

    请确保您没有将控制器方法修饰为默认的GET | PUT | POST | DELETE操作[HttpPost/Put/Get/Delete]属性。我已将此attibute添加到我的vanilla Post控制器操作中,并导致404


    希望这能帮助一些人,因为这可能会让人非常沮丧,让进步停止。

    这个解决方案对我来说很有效

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

    WebApiConfig=>

    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 });
    
    控制器=>

    public class ValuesController : ApiController
    {
    
        [HttpPost]
        public string GetCustomer([FromBody] RequestModel req)
        {
            return "Customer";
        }
    
        [HttpPost]
        public string GetCustomerList([FromBody] RequestModel req)
        {
            return "Customer List";
        }
    }
    
    Url=>

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

    这是每个人的答案,他们知道一切都是正确的,并且检查了50次

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

    要编辑的文件名为
    WebApiConfig.cs

    此外,它应该看起来完全像这样:

    routes.MapHttpRoute(
    name: "API Default",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional });
    
    [Route("api/ControllerName/Summary")]
    [HttpGet]
    public HttpResponseMessage Summary(MyVm vm)
    {
        return null;
    }
    
    [Route("api/ControllerName/FullDetails")]
    [HttpGet]
    public HttpResponseMessage FullDetails()
    {
        return null;
    }
    
    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个小时。

    例如=>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
                );
    
    就这样:)

    结果:
    就我而言,一切都是对的

    1) Web配置已正确配置 2) 路由前缀和路由属性正确

    但我还是得到了错误。在我的例子中,“路由”属性(按F12)指向System.Web.MVc,但不是System.Web.Http,这导致了问题。

    您是否尝试过类似以下操作:

    [HttpGet("Summary")]
    public HttpResponseMessage Summary(MyVm vm)
    {
        return null;
    }
    
    [HttpGet("FullDetails")]
    public HttpResponseMessage FullDetails()
    {
        return null;
    }
    
    您可以将
    [Route(“api/[controller]/[action]”)添加到控制器类中

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

    这样或那样做有什么好处吗?如果我做s