Как игнорировать правило FluentValidation, если объект имеет значение null - PullRequest
0 голосов
/ 08 мая 2019

Как игнорировать правило FluentValidation для нулевого объекта. У меня есть класс валидатора как

public class RequestModel
{
    public int? RecordCount { get; set; } = 100;
}

public class ModelValidator : AbstractValidator<RequestModel>
{
    public ModelValidator()
    {
       When(x => x != null, () =>
       {
           RuleFor(item => item.RecordCount)
             .Cascade(CascadeMode.StopOnFirstFailure)
             .Must(x => x == null || (x.Value > 0 && x.Value <= 1000))
              .WithMessage($"Invalid Limit. Limit must be between 1 and {1000}. (inclusive) ");
        });
    }
}

Здесь я хотел проверить количество записей, только если оно прошло. Но когда я передаю нулевой объект в тело API, он выдает ошибку как

Неверный запрос. Запрос содержит несколько недопустимых параметров или их недостаточно.

1 Ответ

1 голос
/ 08 мая 2019

Я не совсем уверен насчет "api body", но если вы хотите передать нулевой объект, вам нужно переопределить метод Validate в вашем классе ModelValidator.Таким образом, вы можете изящно передать или провалить такой объект в зависимости от вашей бизнес-логики.

Вот пример:

using FluentValidation;
using FluentValidation.Results;
using System;
using System.Linq;

namespace ConsoleApp13
{
    public class RequestModel
    {
        public int? RecordCount { get; set; } = 100;
    }

    public class ModelValidator : AbstractValidator<RequestModel>
    {
        public ModelValidator()
        {
            When(x => x != null, () =>
            {
                RuleFor(item => item.RecordCount)
                  .Cascade(CascadeMode.StopOnFirstFailure)
                  .Must(x => x == null || (x.Value > 0 && x.Value <= 1000))
                   .WithMessage($"Invalid Limit. Limit must be between 1 and {1000}. (inclusive) ");
            });
        }
        public override ValidationResult Validate(ValidationContext<RequestModel> context)
        {
            if (context.InstanceToValidate != null)
            {
                return base.Validate(context);
            }
            //if you want to pass
            return new ValidationResult();
            //if you want to fail
            //return new ValidationResult(new[] { new ValidationFailure("Property", "Your Message") });
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            RequestModel rm1 = new RequestModel { RecordCount = null };
            RequestModel rm2 = new RequestModel { RecordCount = 100 };
            RequestModel rm3 = new RequestModel { RecordCount = -100 };
            RequestModel rm4 = null;

            ModelValidator v = new ModelValidator();

            ValidationResult result1 = v.Validate(rm1);
            ValidationResult result2 = v.Validate(rm2);
            ValidationResult result3 = v.Validate(rm3);
            ValidationResult result4 = v.Validate(rm4);

            Console.WriteLine($"IsValid (rm1): {result1.IsValid}\t| {GetError(result1)}");
            Console.WriteLine($"IsValid (rm2): {result2.IsValid}\t| {GetError(result2)}");
            Console.WriteLine($"IsValid (rm3): {result3.IsValid}\t| {GetError(result3)}");
            Console.WriteLine($"IsValid (rm4): {result4.IsValid}\t| {GetError(result4)}");

            Console.ReadKey();
        }
        static string GetError(ValidationResult result)
        {
            return result.IsValid == false ? string.Join(',', result.Errors.Select(k => k.ErrorMessage).ToArray()) : string.Empty;
        }
    }
}

и результат будет таким:

enter image description here

Надеюсь, это поможет 101

...