在控制器之外使用 ModelState [英] Using ModelState Outside of a Controller
问题描述
我正在努力将 PATCH 端点中的 API 逻辑移至 Mediatr 命令.在应用我的补丁文件时,我通常会检查模型状态,如下所示.通常,我是从控制器执行此操作,因此没有问题,但是当将其移动到 RequestHandler 时,由于我在控制器之外,因此无法再访问模型状态属性.
I'm working on moving my API logic in my PATCH endpoint to a Mediatr Command. When applying my patch document, I usually check the model state like below. Normally, I'm doing this from a controller so there is no issue, but when moving this into a RequestHandler, I no longer have access to the model state property since I'm outside of the controller.
您建议如何处理这个问题?
How would you recommend going about this?
这是我想在控制器之外使用的模型状态逻辑:
Here is the model state logic I'd like to use outside of the controller:
updatePartialValueToReplaceCommand.PatchDoc.ApplyTo(valueToReplaceToPatch, ModelState); // apply patchdoc updates to the updatable valueToReplace
if (!TryValidateModel(valueToReplaceToPatch))
{
return ValidationProblem(ModelState);
}
上下文的其余代码:
补丁端点
[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();
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";
}
}
推荐答案
对于那些感兴趣的人,这就是我最终要做的.也摆脱了那些烦人的魔法字符串!
For those that are interested, here's what I ended up doing. Also got rid of those annoying magic strings!
[HttpPatch("{valueToReplaceId}")]
public IActionResult PartiallyUpdateValueToReplace(int valueToReplaceId, JsonPatchDocument<ValueToReplaceForUpdateDto> patchDoc)
{
var query = new UpdatePartialValueToReplaceCommand(valueToReplaceId, patchDoc, this);
var result = _mediator.Send(query);
return result.Result;
}
public class UpdatePartialValueToReplaceCommand : IRequest<IActionResult>
{
public int ValueToReplaceId { get; set; }
public JsonPatchDocument<ValueToReplaceForUpdateDto> PatchDoc { get; set; }
public Controller Controller { get; set; }
public UpdatePartialValueToReplaceCommand(int valueToReplaceId, JsonPatchDocument<ValueToReplaceForUpdateDto> patchDoc,
Controller controller)
{
ValueToReplaceId = valueToReplaceId;
PatchDoc = patchDoc;
Controller = controller;
}
}
public class UpdatePartialValueToReplaceHandler : IRequestHandler<UpdatePartialValueToReplaceCommand, IActionResult>
{
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<IActionResult> Handle(UpdatePartialValueToReplaceCommand updatePartialValueToReplaceCommand, CancellationToken cancellationToken)
{
if (updatePartialValueToReplaceCommand.PatchDoc == null)
{
return updatePartialValueToReplaceCommand.Controller.BadRequest();
}
var existingValueToReplace = _valueToReplaceRepository.GetValueToReplace(updatePartialValueToReplaceCommand.ValueToReplaceId);
if (existingValueToReplace == null)
{
return updatePartialValueToReplaceCommand.Controller.NotFound();
}
var valueToReplaceToPatch = _mapper.Map<ValueToReplaceForUpdateDto>(existingValueToReplace); // map the valueToReplace we got from the database to an updatable valueToReplace model
updatePartialValueToReplaceCommand.PatchDoc.ApplyTo(valueToReplaceToPatch, updatePartialValueToReplaceCommand.Controller.ModelState); // apply patchdoc updates to the updatable valueToReplace
if (!updatePartialValueToReplaceCommand.Controller.TryValidateModel(valueToReplaceToPatch))
{
return updatePartialValueToReplaceCommand.Controller.ValidationProblem(updatePartialValueToReplaceCommand.Controller.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 updatePartialValueToReplaceCommand.Controller.NoContent();
}
}
这篇关于在控制器之外使用 ModelState的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!