Why is index method not called when action name is not specified

Viewed 741

I have a simple ASP.NET Core API with the following controller:

[ApiController]
[Route("api/[controller]")]
public class HomeController : ControllerBase
{
    public IActionResult Index()
    {
        return Ok("index");
    }

    public IActionResult Get()
    {
        return Ok("get");
    }
}

When I hit URL:

"http://localhost:6001/api/home"

With a GET request, I get the following error:

"The request matched multiple endpoints."

Normally, if I don't specify an action name, shouldn't it call the Index() method?

2 Answers

Both of your endpoints are identical. Use routes to differentiate them. For example:

[ApiController]
[Route("api/[controller]")]
public class HomeController : ControllerBase
{
    [HttpGet]
    public IActionResult Index()
    {
        return Ok("index");
    }

    [HttpGet, Route("data")]
    public IActionResult Get()
    {
        return Ok("get");
    }
}

This would open up:

http://localhost:6001/api/home/

and

http://localhost:6001/api/home/data

respectively using GET

You could also change the verb, for example use HttpGet for one and HttpPost for another.

In ASP.NET Core API, action methods are matched by a combination of HTTP verb used as attribute on the method (which is HttpGet by default if you don't add any) and the route parameter used with it. In that sense both your action methods looks similar to the routing system. It sees two HttpGet method with no route parameter. That's why both method matches the request -

"http://localhost:6001/api/home"

making the routing system confused which to select. That's exactly what the error message is saying.

You need to make your non-default action method more specific, so that the routing mechanism can differentiate between the two. Something like -

[HttpGet("data")]
public IActionResult Get()
{
    return Ok("get");
}

Now your Index method will be matched as default action method with the above URL.

Related