Обзор библиотеки FluentValidation. Часть 5. Условия

от автора

Вы можете задавать условия через методы расширения When и Unless для определения, должны ли выполняться все предыдущие валидаторы (до вызова метода расширения) либо конкретный валидатор в правиле RuleFor. Применение метода расширения When:

// Модель клиента public class Customer {   // Имя   public string? Forename { get; set; }   // Фамилия   public string? Surname { get; set; } }  // Валидатор для модели клиента public class CustomerValidator : AbstractValidator<Customer> {   public CustomerValidator()   {     // Оба свойства (Surname, Forename) должны быть заполнены, если заполнено одно из них     RuleFor(customer => customer.Surname)       .NotNull()       .When(customer => customer.Forename is not null);      RuleFor(customer => customer.Forename)       .NotNull()       .When(customer => customer.Surname is not null);   } }

Метод расширения Unless противоположность методу расширения When, следующий пример кода вернёт тот же результат, что из примера выше, т. к. условие инвертировано:

// Модель клиента public class Customer { ... }  // Валидатор для модели клиента public class CustomerValidator : AbstractValidator<Customer> {   public CustomerValidator()   {     // Оба свойства (Surname, Forename) должны быть заполнены, если заполнено одно из них     RuleFor(customer => customer.Surname)       .NotNull()       .Unless(customer => customer.Forename is null);      RuleFor(customer => customer.Forename)       .NotNull()       .Unless(customer => customer.Surname is null);   } }

По умолчанию FluentValidaton применяет условие When, Unless для всех предыдущих валидаторов в правиле RuleFor. Если возникла необходимость указать условие к валидатору, который непосредственно предшествует методу расширения When, Unless нужно это явно указать через значение перечисления ApplyConditionTo.CurrentValidator, которое передаётся вторым аргументом в метод расширения When, Unless, пример использования с методом расширения When:

// Модель клиента public class Customer {   // Название организации   public string? OrgName { get; set; }   // Имя   public string? Forename { get; set; }   // Фамилия   public string? Surname { get; set; } }  // Валидатор для модели клиента public class CustomerValidator : AbstractValidator<Customer> {   public CustomerValidator()   {     // Должны быть заполнены поля Surname, Forename (одновременно) либо OrgName     RuleFor(customer => customer.Surname)       .NotNull()         .When(customer => customer.OrgName is null && customer.Forename is not null, ApplyConditionTo.CurrentValidator)       .Null()         .When(customer => customer.OrgName is not null && customer.Forename is null, ApplyConditionTo.CurrentValidator);      RuleFor(customer => customer.Forename)       .NotNull()         .When(customer => customer.OrgName is null && customer.Surname is not null, ApplyConditionTo.CurrentValidator)       .Null()         .When(customer => customer.OrgName is not null && customer.Surname is null, ApplyConditionTo.CurrentValidator);        RuleFor(customer => customer.OrgName)         .NotNull()           .When(customer => customer.Surname is null && customer.Forename is null, ApplyConditionTo.CurrentValidator)         .Null()           .When(customer => customer.Surname is not null && customer.Forename is not null, ApplyConditionTo.CurrentValidator);   } }

Обратите внимание, что я выделил дополнительной табуляцией вызов метода расширения When, т. к. указан аргумент ApplyConditionTo.CurrentValidator, чтобы подчеркнуть принадлежность метода расширения When только к предыдущему валидатору.

Если второй параметр ApplyConditionTo явно не указан, он примет значение ApplyConditionTo.AllValidators по умолчанию, которое означает, что условие применяется для всех предыдущих валидаторов в правиле RuleFor.

Если возникла необходимость указать общее условие для группы правил RuleFor, можно использовать метод When «верхнего уровня» (из базового класса AbstractValidator<T>) вместо метода расширения When, который крепится в конце правила либо валидатора:

// Модель клиента public class Customer { ... }  // Валидатор для модели клиента public class CustomerValidator : AbstractValidator<Customer> {   public CustomerValidator()   {     // Должны быть заполнены поля Surname, Forename (одновременно) либо OrgName.     // Если OrgName не заполнен, то     When(customer => customer.OrgName is null, () =>     {       // Surname должен быть заполнен       RuleFor(customer => customer.Surname)         .NotNull();       // Forename должен быть заполнен       RuleFor(customer => customer.Forename)         .NotNull();       // OrgName должен быть не заполнен       RuleFor(customer => customer.OrgName)         .Null();     })     // Otherwise выполняется в случае, если условие When не удовлетворено (false)     .Otherwise(() =>     {       // Surname должен быть не заполнен       RuleFor(customer => customer.Surname)         .Null();       // Forename должен быть не заполнен       RuleFor(customer => customer.Forename)         .Null();       // OrgName должен быть заполнен       RuleFor(customer => customer.OrgName)         .NotNull();     });   } }

Вызов метода Otherwise опционален, его можно вызывать непосредственно после вызова When «верхнего уровня». Выполняется в случае, если условие When не удовлетворено (false).

Предыдущая часть Следующая часть


ссылка на оригинал статьи https://habr.com/ru/articles/799173/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *