我正在将控制器中的API逻辑抽象为Mediatr命令和查询。我的POST和PUT端点通过标准.NET Core模型绑定验证进行了验证,但是我的PATCH端点的patchdoc需要检查控制器中模型的有效性。由于它是ControllerBase的一部分,因此我无法再访问该上下文。
你们都将如何建议您这样做?
补丁端点
[HttpPatch("{valueToReplaceId}")]
public IActionResult PartiallyUpdateValueToReplace(int valueToReplaceId, JsonPatchDocument<ValueToReplaceForUpdateDto> patchDoc)
{
var query = new UpdatePartialValueToReplaceCommand(valueToReplaceId, patchDoc);
var result = _mediator.Send(query);
switch (result.Result.ToUpper())
{
case "NOTFOUND":
return NotFound();
case "NOCONTENT":
return NoContent();
case "BADREQUEST":
return BadRequest();
default:
return BadRequest();
}
}
UpdatePartialValueToReplaceCommand
public class UpdatePartialValueToReplaceCommand : IRequest<string>
{
public int ValueToReplaceId { get; set; }
public JsonPatchDocument<ValueToReplaceForUpdateDto> PatchDoc { get; set; }
public UpdatePartialValueToReplaceCommand(int valueToReplaceId, JsonPatchDocument<ValueToReplaceForUpdateDto> patchDoc)
{
ValueToReplaceId = valueToReplaceId;
PatchDoc = patchDoc;
}
}
((BROKEN)UpdatePartialValueToReplaceHandler
public class UpdatePartialValueToReplaceHandler : IRequestHandler<UpdatePartialValueToReplaceCommand, string>
{
private readonly IValueToReplaceRepository _valueToReplaceRepository;
private readonly IMapper _mapper;
public UpdatePartialValueToReplaceHandler(IValueToReplaceRepository valueToReplaceRepository
, IMapper mapper)
{
_valueToReplaceRepository = valueToReplaceRepository ??
throw new ArgumentNullException(nameof(valueToReplaceRepository));
_mapper = mapper ??
throw new ArgumentNullException(nameof(mapper));
}
public async Task<string> Handle(UpdatePartialValueToReplaceCommand updatePartialValueToReplaceCommand, CancellationToken cancellationToken)
{
if (updatePartialValueToReplaceCommand.PatchDoc == null)
{
return "BadRequest";
}
var existingValueToReplace = _valueToReplaceRepository.GetValueToReplace(updatePartialValueToReplaceCommand.ValueToReplaceId);
if (existingValueToReplace == null)
{
return "NotFound";
}
var valueToReplaceToPatch = _mapper.Map<ValueToReplaceForUpdateDto>(existingValueToReplace); // map the valueToReplace we got from the database to an updatable valueToReplace model
updatePartialValueToReplaceCommand.PatchDoc.ApplyTo(valueToReplaceToPatch, ModelState); // apply patchdoc updates to the updatable valueToReplace -- THIS DOESN'T WORK IN A MEDIATR COMMAND BECAUSE I DON'T HAVE CONTROLLERBASE CONTEXT
if (!TryValidateModel(valueToReplaceToPatch))
{
return ValidationProblem(ModelState);
}
_mapper.Map(valueToReplaceToPatch, existingValueToReplace); // apply updates from the updatable valueToReplace to the db entity so we can apply the updates to the database
_valueToReplaceRepository.UpdateValueToReplace(existingValueToReplace); // apply business updates to data if needed
_valueToReplaceRepository.Save(); // save changes in the database
return "NoContent";
}
}
我遇到了相同的情况,并通过释放ModelState(更改的代码)解决了这个问题:
updatePartialValueToReplaceCommand.PatchDoc.ApplyTo(valueToReplaceToPatch);
//if (!TryValidateModel(valueToReplaceToPatch))
//{
//return ValidationProblem(ModelState);
//}