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

Вы можете задавать условия через методы расширения When и Unless для определения, должны ли выполняться все предыдущие валидаторы (до вызова метода расширения) либо конкретный валидатор в правиле RuleFor. Применение метода расширения When:
// Модель клиента
public class Customer
{
// Имя
public string? Forename { get; set; }
// Фамилия
public string? Surname { get; set; }
}
// Валидатор для модели клиента
public class CustomerValidator : AbstractValidator
{
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
{
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
{
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) вместо метода расширения When, который крепится в конце правила либо валидатора:
// Модель клиента
public class Customer { ... }
// Валидатор для модели клиента
public class CustomerValidator : AbstractValidator
{
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).
← Предыдущая часть
