ASP.NET Core 6 Web API:如何区分 HttpGet Verb/Actions 的不同变体之间的路由?

blo*_*s4t 1 asp.net-core asp.net-core-webapi .net-6.0

我有这个控制器定义。我收到一个错误,如下所示。如何区分HttpGet动词/动作的几种变体之间的路由?

这个错误似乎很明显,但我想看看如何解决这个问题。谢谢!

操作的冲突方法/路径组合“GET api/Order” - Ordering.Api.Controllers.OrderController.Orders (Ordering.Api)、Ordering.Api.Controllers.OrderController.Orders (Ordering.Api)、Ordering.Api.Controllers。 OrderController.Order (Ordering.Api)。对于 Swagger/OpenAPI 3.0,操作需要独特的方法/路径组合。使用 ConflictingActionsResolver 作为解决方法

控制器:

[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;
    }
}
Run Code Online (Sandbox Code Playgroud)

dav*_*owl 5

假设这些参数可以通过路径区分,您应该在路由模式中指定参数:

[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;
    }
}
Run Code Online (Sandbox Code Playgroud)

不过,名称和 id 参数之间仍然存在冲突。路由系统如何区分api/Order/1api/Order/john?那么你可以使用路由约束来进一步消除歧义:

[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;
    }
}
Run Code Online (Sandbox Code Playgroud)