【发布时间】:2019-05-28 02:28:38
【问题描述】:
我有以下控制器:
[Route("xapi/statements")] << -- NOTICE THE ROUTE
[Produces("application/json")]
public class StatementsController : ApiControllerBase
随着他的行动
/// <summary>
/// Stores a single Statement with the given id.
/// </summary>
/// <param name="statementId"></param>
/// <param name="statement"></param>
/// <returns></returns>
[AcceptVerbs("PUT", "POST", Order = 1)]
public async Task<IActionResult> PutStatement([FromQuery]Guid statementId, [ModelBinder(typeof(StatementPutModelBinder))]Statement statement)
{
await _mediator.Send(PutStatementCommand.Create(statementId, statement));
return NoContent();
}
/// <summary>
/// Create statement(s) with attachment(s)
/// </summary>
/// <param name="model"></param>
/// <returns>Array of Statement id(s) (UUID) in the same order as the corresponding stored Statements.</returns>
[HttpPost(Order = 2)]
[Produces("application/json")]
public async Task<ActionResult<ICollection<Guid>>> PostStatements(StatementsPostModelBinder model)
{
ICollection<Guid> guids = await _mediator.Send(CreateStatementsCommand.Create(model.Statements));
return Ok(guids);
}
操作按以下顺序执行: 1. 放置语句 2. 后声明
但只有在提供了 statementId 参数时才应触发 PutStatement。事实并非如此。
如果语句有任何附件,我正在使用 2 个模型绑定器将流的内容解析为 application/json 或 multipart/form-data。 1.StatementPutModelBinder 2.StatementsPostModelBinder
如果没有提供 statementId 参数,我如何防止执行操作? 例如。 /xapi/statements/ => 命中 PutStatement
【问题讨论】:
-
如果您没有提供 statementId,那么我假设您的
Statement模型也将丢失它? -
根据 xAPI 规范,它在语句模型上是可选的,但如果提供,它们必须相等。这发生在我为每个命令提供验证的中介管道期间。
-
您可以在 StatementPutModelBinder 中检查 statementid 不是空的 guid,如果它是拒绝它还是您不想要一个 badrequest 结果?
-
如果请求是 /xapi/statements?statementId=000..-000 则请求被拒绝,因为 statementId 为 null、空或与语句模型上的可选 id 不匹配。但如果请求是 /xapi/statements,则 PutStatement 被命中。这不是我想要的。如果方法是 POST,它应该命中 PostStatements,否则它是错误的请求。
-
是的,你的情况有点棘手。您接受 put 和 post 到一个端点,然后接受 post 到另一个基本上是相同路由的端点。我将删除第一个端点的接受帖子,并使 statementid 成为路由的一部分,即 Route("{statementId:guid}")。这将强制放置一个 id,这是您想要的,然后让您的帖子处理来自查询的空 statementId
标签: asp.net-mvc asp.net-core asp.net-core-webapi