在控制器之外使用 ModelState [英] Using ModelState Outside of a Controller

查看:23
本文介绍了在控制器之外使用 ModelState的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力将 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆