Проверка нескольких свойств одним сообщением

#fluentvalidation

#fluentvalidation

Вопрос:

Я пытаюсь проверить класс, который имеет три обязательных свойства.
Если одно или более из них равно null, это должно вызвать одно сообщение проверки.
Есть ли идиоматический способ описать это в fluent validator?

Я смотрю на зависимые правила, но внизу страницы документации не рекомендуется их использовать.
Кроме того, я все еще хочу проверить все три свойства. Я просто не хочу дублирующихся сообщений.
Я заметил наборы правил, но они, похоже, служат другой цели.

В качестве альтернативы я мог бы создать валидатор специально для этих трех параметров, но без сообщения, а затем подключить новый валидатор к исходному. Тогда, я думаю, я могу передать этому одно сообщение.
Но это слишком много церемоний для системы, которая построена на том, чтобы быть читаемой.

Итак, ищем удобный способ выразить проверку для трех полей с одним сообщением в качестве результата.

Ответ №1:

Есть 3 основных способа, которыми вы можете сделать это с помощью FluentValidation: условия, зависимые правила или пользовательское правило.

Условия

Вы можете использовать 3 отдельных объявления правил с When условиями, чтобы гарантировать получение только одного сообщения проверки.

 RuleFor(x => x.Property1).NotNull()
  .WithMessage("At least one is required");

RuleFor(x => x.Property2).NotNull()
  .When(x => x.Property2 != null)
  .WithMessage("At least one is required");

RuleFor(x => x.Property3).NotNull()
  .When(x => x.Property1 != null amp;amp; x.Property2 != null)
  .WithMessage("At least one is required");
  

Зависимые правила

 RuleFor(x => x.Property1).NotNull()
  .WithMessage("At least one is required")
  .DependentRules(() => {
      RuleFor(x => x.Property2).NotNull()
       .WithMessage("At least one is required")
       .DependentRules(() => {
          RuleFor(x => x.Property3).NotNull().WithMessage("At least one is required");
       });
   });
  

Мне не особенно нравится этот подход — я думаю, что его трудно читать (отсюда предупреждение в документации), но если вам нравится этот подход, он будет работать просто отлично.

Пользовательская логика

 RuleFor(x => x)
  .Must(x => x.Property1 != null amp;amp; x.Property2 != null amp;amp; x.Property3 != null)
  .WithMessage("At least one is required");
  

Этот подход немного отличается, поскольку он создает правило уровня модели, поэтому сообщение об ошибке будет связано со всей моделью, а не с конкретным свойством.

Ответ №2:

Остановите средство проверки при сбое первого правила, установив CascadeMode свойство:

 public class MyClassValidator : AbstractValidator<MyClass>
{
    public DestinationDeviceValidator()
    {
        this.CascadeMode = CascadeMode.Stop;

        this.RuleFor(x => x.Property1)
            .NotNull();

        this.RuleFor(x => x.Property2)
            .NotNull();

        this.RuleFor(x => x.Property3)
            .NotNull();
    }
}
  

Комментарии:

1. Да, это тоже хороший вариант, если предположить, что это единственные три свойства