ASPNET Core Routing

Viewed 66

I had a problem with incorrect route setup, which I've fixed, but I don't fully understand why the fix worked.

    [ApiController]
    [Route("api/[controller]")
    public class DetailsController : ControllerBase
    {
        [HttpGet]
        [Route("api/[controller]/{transactNo}")]
        public IActionResult Detail(int transactNo)
        {
        ...

When I was calling api/details/123 I was getting route not found, until I removed the Route attribute from the class. So I guess they were conflicting, but why?

3 Answers

Placing a RouteAttribute on a controller is different to placing one on an action.

  • On a controller, it defines the route that all actions belonging to that controller will be prefixed with
  • On an action, it defines the route to be concatenated with the prefixed route

That means when you added both attributes, you would have been able to call the action at:

https://localhost:44338/api/details/api/details/1
                        ^^^^^^^^^^^ ^^^^^^^^^^^^^
                  from controller         ^
                                    from action
                         

The endpoint's route is the controller's route api/[controller] concatenated with the action's route api/[controller]/{transactNo}.

In your case, the endpoint's route is api/[controller]/api/[controller]/{transactNo}.

You need simplify the action's route like :

[HttpGet]
[Route("{transactNo}")]
public IActionResult Detail(int transactNo)
{

If you want redefine the endpoint's route only from the action, the action's route have to begin with / :

[HttpGet]
[Route("/api/[controller]/{transactNo}")]
public IActionResult Detail(int transactNo)
{

You can replace route attribtue on action to [HttpGet("{transactNo}")] and change the route attribute on the controller to [Route("api/[controller]/[action]")]

[ApiController]
[Route("api/[controller]/[action]")]
public class DetailsController : ControllerBase
{
    [HttpGet("{transactNo}")]
    public IActionResult Detail(int transactNo)
    {
        ...
    }
}

now you can call this url : api/Details/Detail/123

Related