2

The following code

public class OrderController : Controller
{   
    // GET api/values
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/values/5
    public string Get(int id)
    {
        return "value";
    }
}

It can work well on ASP.NET 4.5,but it doesn't work on dotnet core 1.1 .The Error Messsage:

fail: Microsoft.AspNetCore.Mvc.Internal.ActionSelector[1] Request matched multiple actions resulting in ambiguity. Matching actions: WebAPI.Controllers.OrderController.Get (WebAPI) WebAPI.Controllers.OrderController.Get (WebAPI)

fail: Microsoft.AspNetCore.Server.Kestrel[13] Connection id "0HL3F88N44HR6": An unhandled exception was thrown by the application. Microsoft.AspNetCore.Mvc.Internal.AmbiguousActionException: Multiple actions matched. The following actions matched route data and had all constraints satisfied: WebAPI.Controllers.OrderController.Get (WebAPI) WebAPI.Controllers.OrderController.Get (WebAPI)

Siying Wang
  • 71
  • 2
  • 4

3 Answers3

2

It is not a problem of Asp.Net.Core, exact the same behaviour is in both MVC4 and MVC5.

ASP.NET MVC does not support method overloading, there is a lot of SO questions and articles about this:

There could be a set of solutions to get the desired behaviour, one of commons are:

First - to use built-in attribute, derived from ActionFilterAttribute or ActionMethodSelectorAttribute in MVC4 (it is the base class for retrieving the required action while processing your request). For example ActionNameAttribute, HttpGetAttribute, HttpPostAttribute, etc:

public IEnumerable<string> Get()
{
    return new string[] { "value1", "value2" };
}

[ActionName("GetById")
public string Get(int id)
{
    return "value";
}

Or simply rename your method.

Another solution is to create your own attribute, derived from ActionFilterAttribute as suggested at second link.

When I faced this problem, I solved this by passing a nullable parameter in the following manner:

public object Get(int? id)
{
    if (id == null)
        return new string[] { "value1", "value2" };

    var passedId = (int) id;
    return GetValueByPassedId(passedId);
}
Community
  • 1
  • 1
Mikhail Tulubaev
  • 4,141
  • 19
  • 31
1

You can fix this by adding HttpGet attribute, like this.

[HttpGet("{id}")]
// GET api/values/5
public string Get(int id)
{
    return "value";
}

It is because in ASP.NET 5, for web API routing, Routes.MapHttpRoute method was used and for ASP.NET MVC Routes.MapRoute method. In ASP.NET Core, Routes.MapRoute method is used.

Anuraj
  • 18,859
  • 7
  • 53
  • 79
0

Try like this:

// GET api/values/5
[HttpGet("Get/{id}"]
public string Get(int id)
{
    return "value";
}
Cristian Szpisjak
  • 2,429
  • 2
  • 19
  • 32