Проверка 2 моделей с помощью валидатора ModelState.IsValid и FluentValidation в .NET Core 2 - PullRequest
0 голосов
/ 07 июня 2018

В моем проекте API у меня есть несколько конечных точек для простых операций CRUD.Конечные точки используют FluentValidation для проверки предоставленных моделей путем добавления валидаторов в DI и использования ModelState.IsValid.

ModelState.IsValid отлично работает, когда в качестве параметра используется только одна модель, но как только у меня будет несколько моделейзатем проверяется только первое получение, следующий пример делает эту проблему более ясной:

Моя UPDATE операция конечной точки принимает 2 параметра (идентификатор и модель):

    public async Task<IActionResult> UpdateMedium([CustomizeValidator(RuleSet = ValidationClass.UPDATE)] [FromRoute] long id, [FromBody] Medium model)
    {
        if (!this.ModelState.IsValid)
        {
            return this.BadRequest(this.ModelState);
        }

        if (id != model.MediumID)
        {
            return this.BadRequest();
        }

        // Etc....

    }

this.ModelState.IsValid теперь проверяется только первая модель (Id), а вторая модель get игнорируется.Каков наилучший подход для проверки обеих моделей?

Параметр Id, очевидно, довольно прост, но я все равно сделал для него валидатор FluentValidation (на случай, если в будущем мы захотим добавить к нему больше проверочной логики):

public class IdValidator : AbstractValidator<long>
{
    public IdValidator()
    {
        RuleFor(r => r).NotEmpty().WithMessage("Id is empty.");
    }
}

Дополнительно,Средство проверки модели Medium выглядит следующим образом:

    public class MediumValidator : AbstractValidator<Medium>
    {

        public MediumValidator()
        {
            RuleSet(ValidationClass.CREATE, Create);
            RuleSet(ValidationClass.UPDATE, Update);
        }

        private void Create()
        {
            RuleFor(r => r.InsertDateTime).Empty().WithMessage("{PropertyName} is not empty.");
            RuleFor(r => r.InsertUserID).Empty().WithMessage("{PropertyName} is not empty.");
            RuleFor(r => r.SolutionID).Empty().WithMessage("{PropertyName} is not empty.");
            RuleFor(r => r.Name).NotEmpty().WithMessage("{PropertyName} is not filled in.");
            RuleFor(r => r.Name).MaximumLength(100).WithMessage("The length of {PropertyName} must be {MaxLength} characters or fewer. You entered {TotalLength} characters.");
        }

        private void Update()
        {
            RuleFor(r => r.UpdateDateTime).Empty().WithMessage("{PropertyName} is not empty.");
            RuleFor(r => r.UpdateUserID).Empty().WithMessage("{PropertyName} is not empty.");
            RuleFor(r => r.MediumID).NotEmpty().WithMessage("{PropertyName} is empty.");
            RuleFor(r => r.Name).NotEmpty().WithMessage("{PropertyName} is not filled in.");
            RuleFor(r => r.Name).MaximumLength(100).WithMessage("The length of {PropertyName} must be {MaxLength} characters or fewer. You entered {TotalLength} characters.");
        }

    }

Возможно, мне следует использовать модель только в качестве параметра, а затем просто сделать поле идентификатора обязательным?

ОБНОВЛЕНИЕ

Настройка FluentValidation при запуске:

services.AddMvc()
            .AddFluentValidation(fv =>
            {
                fv.RunDefaultMvcValidationAfterFluentValidationExecutes = false;
            });

            // Add fluent validators
            services.AddTransient<IValidator<long>, IdValidator>();
            services.AddTransient<IValidator<Medium>, MediumValidator>();

ОБНОВЛЕНИЕ2:

Я использую сваггер для проверки конечной точки (ввод JSON).

1 Ответ

0 голосов
/ 07 июня 2018

На данный момент я реализовал другой подход.Для операции UPDATE я теперь вручную добавляю ошибки модели Medium к ModelState:

var validator = new MediumValidator();
var result = validator.Validate(model, ruleSet: ValidationClass.UPDATE);
result.AddToModelState(this.ModelState, null);

if (!this.ModelState.IsValid)
{
    return this.BadRequest(this.ModelState);
}

. Всегда приветствуются лучшие решения!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...