Home > other >  ASP.NET Core 6 Web API : how to differentiate routing between different variations of a HttpGet Verb
ASP.NET Core 6 Web API : how to differentiate routing between different variations of a HttpGet Verb

Time:08-29

I have this controller definition. I get an error which is shown here. How do I differentiate routing between several variations of a HttpGet verb/actions?

The error seems obvious but I am looking to see how to solve this. thanks!

Conflicting method/path combination "GET api/Order" for actions - Ordering.Api.Controllers.OrderController.Orders (Ordering.Api), Ordering.Api.Controllers.OrderController.Orders (Ordering.Api), Ordering.Api.Controllers.OrderController.Order (Ordering.Api). Actions require a unique method/path combination for Swagger/OpenAPI 3.0. Use ConflictingActionsResolver as a workaround

Controller:

[Route("api/[controller]")]
[ApiController]
public class OrderController : ControllerBase
{
    private IMediator _mediator;

    public OrderController(IMediator mediator)
    {
        _mediator = mediator;
    }

    [HttpGet("", Name = "Get All Orders")]
    public async Task<ActionResult<IEnumerable<OrderVm>>> Orders()
    {
        // construct query
        var query = new AllOrdersQuery();
        var orders = await _mediator.Send(query);
        return orders;
    }

    [HttpGet("", Name = "Get Orders by Username")]
    public async Task<ActionResult<IEnumerable<OrderVm>>> Orders(string username)
    {
        // construct query
        var query = new OrdersByUsernameQuery(username);
        var orders = await _mediator.Send(query);
        return orders;
    }

    [HttpGet("", Name = "Get Order by Id")]
    public async Task<ActionResult<OrderVm>> Order(int id)
    {
        // construct query
        var query = new OrderByIdQuery(id);
        var order = await _mediator.Send(query);
        return order;
    }
}

CodePudding user response:

Assuming those parameters are distinguishable via the path, you should specify the parameter in the route pattern:

[Route("api/[controller]")]
[ApiController]
public class OrderController : ControllerBase
{
    private IMediator _mediator;
    public OrderController(IMediator mediator)
    {
        _mediator = mediator;
    }

    [HttpGet(Name = "Get All Orders")]
    public async Task<ActionResult<IEnumerable<OrderVm>>> Orders()
    {
        // construct query
        var query = new AllOrdersQuery();
        var orders = await _mediator.Send(query);
        return orders;
    }

    [HttpGet("{name}", Name = "Get Orders by Username")]
    public async Task<ActionResult<IEnumerable<OrderVm>>> Orders(string username)
    {
        // construct query
        var query = new OrdersByUsernameQuery(username);
        var orders = await _mediator.Send(query);
        return orders;
    }

    [HttpGet("{id}", Name = "Get Order by Id")]
    public async Task<ActionResult<OrderVm>> Order(int id)
    {
        // construct query
        var query = new OrderByIdQuery(id);
        var order = await _mediator.Send(query);
        return order;
    }
}

This still has a conflict between the name and id parameter though. How can the routing system distinguish between api/Order/1 and api/Order/john? Well you can use route constraints to disambiguate further:

[Route("api/[controller]")]
[ApiController]
public class OrderController : ControllerBase
{
    private IMediator _mediator;
    public OrderController(IMediator mediator)
    {
        _mediator = mediator;
    }

    [HttpGet(Name = "Get All Orders")]
    public async Task<ActionResult<IEnumerable<OrderVm>>> Orders()
    {
        // construct query
        var query = new AllOrdersQuery();
        var orders = await _mediator.Send(query);
        return orders;
    }

    [HttpGet("{name:string}", Name = "Get Orders by Username")]
    public async Task<ActionResult<IEnumerable<OrderVm>>> Orders(string username)
    {
        // construct query
        var query = new OrdersByUsernameQuery(username);
        var orders = await _mediator.Send(query);
        return orders;
    }

    [HttpGet("{id:int}", Name = "Get Order by Id")]
    public async Task<ActionResult<OrderVm>> Order(int id)
    {
        // construct query
        var query = new OrderByIdQuery(id);
        var order = await _mediator.Send(query);
        return order;
    }
}
  • Related