Выдавать исключение при сбое одного правила FluentValidation

Можно ли с помощью FluentValidation создать исключение при сбое одного правила? Например, я хотел бы вызвать Validate() и для первого правила, приведенного ниже, чтобы просто проверить, а второе, чтобы генерировать исключение, если оно ложно.

RuleFor(x => x.Title)
    .NotEmpty()
    .WithMessage("Please add a title for the project");

RuleFor(x => x.UserId)
    .NotEmpty()
    .WithMessage("User not supplied");

Вероятно, я пытаюсь заставить FluentValidation делать то, для чего он не предназначен. И я знаю о методе ValidateAndThrow(), но он вызовет исключение при любом сбое.


person Digbyswift    schedule 19.06.2011    source источник


Ответы (2)


Да. Попробуйте что-нибудь в этом духе -

Добавьте FluentValidation и FluentValidation.TestHelper в свои директивы.

    private readonly IValidator<ItemViewModel> validator = new ItemValidator(); 
    //Assumes your fluent validation is in ItemValidator and your view model is ItemViewModel

    [Test]
    public void Headline_ShouldNotBeEmpty()
    {
        validator.ShouldHaveValidationErrorFor(f => f.message, string.Empty);
    }
person Gikote    schedule 20.06.2011
comment
Итак, вы предлагаете создать класс Validator для определенного свойства/объекта, в моем примере выше это будет UserId. Единственной целью этого валидатора будет создание исключения при неудачной проверке UserId? - person Digbyswift; 23.06.2011
comment
Проголосовали против, потому что первоначальный вопрос был не о тестировании, а о самих фактических определениях правил. - person JBert; 23.08.2017

Обычно лучше проверить все свойства, а затем сообщить результат, хотя может быть случай, когда нет смысла продолжать проверку (в моем случае это было, когда в запросе отсутствовал идентификатор «арендатора»).

Просто измените второе правило на что-то вроде этого (проверено с помощью Automapper 5.2, C# 6):

RuleFor(x => x.Title)
    .NotEmpty()
    .WithMessage("Please add a title for the project");

RuleFor(x => x.UserId)
    .NotEmpty()
    .OnAnyFailure(x =>
    {
        throw new ArgumentException(nameof(x.UserId));
    });
  • Если вы вызываете IValidator.Validate(...) и первое правило не работает, оно просто будет указано в списке Errors результата.
  • Если второе правило не выполняется, вызов Validate вызовет ArgumentException и, очевидно, никакого результата не будет возвращено.
  • Если бы вы вызвали метод расширения ValidateAndThrow, то он либо просто возвратился бы, либо выдал бы ArgumentException, если второе правило не сработало, либо выдал бы ValidationException, если одно из других правил не сработало.
person JBert    schedule 05.02.2017