路由:解决带查询参数的不明确请求
Routing: Solve ambigous requests with query parameters
鉴于下面的 RecordsController,以下请求应该是可能的并相应地映射到端点
- /api/Records
- /api/Records/9b858599-7639-45da-acd6-a1323fb019b5
- /api/Records/9b858599-7639-45da-acd6-a1323fb019b5?asOf=2022-01-01
- /api/Records/9b858599-7639-45da-acd6-a1323fb019b5?From=2022-01-01&To=2022-03-01
映射到:
- GetAll(Guid id)
- 获取(Guid id)
- GetAsOf(Guid id1, [FromQuery] string asOf)
- GetHistory(Guid id2,[FromQuery] 字符串来自,[FromQuery] 字符串至)
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
namespace WebApplication1.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class RecordsController : ControllerBase
{
private readonly ILogger<RecordsController> _logger;
public RecordsController(ILogger<RecordsController> logger)
{
_logger = logger;
}
[HttpGet()]
public ActionResult<IEnumerable<Record>> GetAll()
{
_logger.LogInformation("GetAll() was used");
return Ok();
}
[HttpGet("{id:Guid}")]
public ActionResult<Record> Get(Guid id)
{
_logger.LogInformation("Get() was used");
return Ok();
}
[HttpGet("{id1:Guid}")]
public ActionResult<IEnumerable<Record>> GetAsOf(Guid id1, [FromQuery] string asOf)
{
_logger.LogInformation("GetAsOf() was used");
return Ok();
}
[HttpGet("{id2:Guid}")]
public ActionResult<IEnumerable<Record>> GetHistory(Guid id2, [FromQuery] string from, [FromQuery] string to)
{
_logger.LogInformation("GetHistory() was used");
return Ok();
}
}
public class Record
{
public Guid Id { get; set; }
public string Comment { get; set; } = string.Empty;
}
}
这没有按预期工作。
上述实现会导致 AmbiguousMatchException。
使用 IRouteTemplateProvider.Order
有可能影响此行为,但随后请求 2. - 4. 被路由到具有最低顺序的端点。
除了将 FromQuery
更改为 FromRoute
之外,您是否看到任何可能性?
谢谢!
方法 2-4 确实不明确,因为它们都是相同的端点,只是具有不同的查询参数。因此,您要么需要使它们具有不同的路由,要么可以将端点表示为具有所有可能查询参数的单个方法,然后从那里使用存在的查询参数映射到特定方法。
HttpGet("{id:Guid}")]
public ActionResult<Record> Get(Guid id, [FromQuery] string asOf, [FromQuery] string from, [FromQuery] string to)
{
if (asOf != null) return GetAsOf(id, asOf);
if (from != null && to != null) return GetHistory(id, from, to);
return Get(id);
}
public ActionResult<Record> Get(Guid id)
{
_logger.LogInformation("Get() was used");
return Ok();
}
public ActionResult<IEnumerable<Record>> GetAsOf(Guid id, string asOf)
{
_logger.LogInformation("GetAsOf() was used");
return Ok();
}
public ActionResult<IEnumerable<Record>> GetHistory(Guid id2, [FromQuery] string from, [FromQuery] string to)
{
_logger.LogInformation("GetHistory() was used");
return Ok();
}
鉴于下面的 RecordsController,以下请求应该是可能的并相应地映射到端点
- /api/Records
- /api/Records/9b858599-7639-45da-acd6-a1323fb019b5
- /api/Records/9b858599-7639-45da-acd6-a1323fb019b5?asOf=2022-01-01
- /api/Records/9b858599-7639-45da-acd6-a1323fb019b5?From=2022-01-01&To=2022-03-01
映射到:
- GetAll(Guid id)
- 获取(Guid id)
- GetAsOf(Guid id1, [FromQuery] string asOf)
- GetHistory(Guid id2,[FromQuery] 字符串来自,[FromQuery] 字符串至)
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
namespace WebApplication1.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class RecordsController : ControllerBase
{
private readonly ILogger<RecordsController> _logger;
public RecordsController(ILogger<RecordsController> logger)
{
_logger = logger;
}
[HttpGet()]
public ActionResult<IEnumerable<Record>> GetAll()
{
_logger.LogInformation("GetAll() was used");
return Ok();
}
[HttpGet("{id:Guid}")]
public ActionResult<Record> Get(Guid id)
{
_logger.LogInformation("Get() was used");
return Ok();
}
[HttpGet("{id1:Guid}")]
public ActionResult<IEnumerable<Record>> GetAsOf(Guid id1, [FromQuery] string asOf)
{
_logger.LogInformation("GetAsOf() was used");
return Ok();
}
[HttpGet("{id2:Guid}")]
public ActionResult<IEnumerable<Record>> GetHistory(Guid id2, [FromQuery] string from, [FromQuery] string to)
{
_logger.LogInformation("GetHistory() was used");
return Ok();
}
}
public class Record
{
public Guid Id { get; set; }
public string Comment { get; set; } = string.Empty;
}
}
这没有按预期工作。 上述实现会导致 AmbiguousMatchException。
使用 IRouteTemplateProvider.Order
有可能影响此行为,但随后请求 2. - 4. 被路由到具有最低顺序的端点。
除了将 FromQuery
更改为 FromRoute
之外,您是否看到任何可能性?
谢谢!
方法 2-4 确实不明确,因为它们都是相同的端点,只是具有不同的查询参数。因此,您要么需要使它们具有不同的路由,要么可以将端点表示为具有所有可能查询参数的单个方法,然后从那里使用存在的查询参数映射到特定方法。
HttpGet("{id:Guid}")]
public ActionResult<Record> Get(Guid id, [FromQuery] string asOf, [FromQuery] string from, [FromQuery] string to)
{
if (asOf != null) return GetAsOf(id, asOf);
if (from != null && to != null) return GetHistory(id, from, to);
return Get(id);
}
public ActionResult<Record> Get(Guid id)
{
_logger.LogInformation("Get() was used");
return Ok();
}
public ActionResult<IEnumerable<Record>> GetAsOf(Guid id, string asOf)
{
_logger.LogInformation("GetAsOf() was used");
return Ok();
}
public ActionResult<IEnumerable<Record>> GetHistory(Guid id2, [FromQuery] string from, [FromQuery] string to)
{
_logger.LogInformation("GetHistory() was used");
return Ok();
}