当我尝试有2个“Get”方法时,我一直得到这个错误

发现了多个与请求:webapi匹配的操作

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

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

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

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

当前回答

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

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

其他回答

我在尝试用额外的操作来增强我的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();
}

对于第一种方法,结合“dual”路由绑定:

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调用的路由和对额外动作的调用。

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

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

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

例如=> 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
            );

就是这样。

结果:

在WebApiConfig.cs中,你的路线图可能是这样的:

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传递变量,我建议你走那条路。否则,你需要在请求的主体中发送对象,当你做一个GET时,这不是很HTTP(虽然它是有效的,只是在MyVm前面使用[FromBody])。

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

确保你没有装饰你的控制器方法默认的GET|PUT|POST|DELETE动作与[HttpPost/ PUT / GET / DELETE]属性。我已经将此属性添加到我的香草后控制器动作,它导致404。

希望这能帮助到一些人,因为它可能会非常令人沮丧,并导致进展停滞。