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;
}
}