@OwDafuq

FluentValidator, как валадировать св-во во втором валидаторе, исходя из первого валидатора?

Допустим, что есть такие интерфейсы и классы их реализующие:
class FirstTest : IHasId, IHasGuid
{
    public int Id { get; set; }

    public Guid Guid { get; set; }
}

class SecondTest : IHasId, IHasString
{
    public int Id { get; set; }

    public string String { get; set; }
}

interface IHasId
{
    int Id { get; set; }
}

interface IHasGuid
{
    Guid Guid { get; set; }
}

interface IHasString
{
    string String { get; set; }
}


Вопрос, как сделать общий валидатор для IHasId, чтобы его можно было использовать так, что если валидатор для IHasId не смог найти значение, например, в БД, то валидация для IHasGuid или IHasString не использовалась?
Не хочется писать один и тот же валидатор для 2-х разных классов, где будет одинаковый метод валидации Id.
Как бы хотелось видеть валидаторы:
class SecondTestValidator : AbstractValidator<SecondTest>
{
    public SecondTestValidator()
    {
        Include(new IdValidator()).DependentRules(idValidator =>
        {
            if (idValidator.IdValid)
            {
                RuleFor(x => x.String).NotEmpty().MinimumLength(20).MaximumLength(50).Matches("[a-z]");
            }
        });
    }
}

class FirstTestValidator : AbstractValidator<FirstTest>
{
    public FirstTestValidator()
    {
        Include(new IdValidator()).DependentRules(idValidator =>
        {
            if (idValidator.IdValid)
            {
                RuleFor(x => x.Guid).NotEmpty();
            }
        });
    }
}

Но Include возвращает void.

Такой вариант тоже не сработал, проверка вызывается в любом случае:
class FirstTestValidator : AbstractValidator<FirstTest>
{
    public FirstTestValidator()
    {
        Include(new IdValidator(() => RuleFor(x => x.Guid).NotEmpty());
    }
}

class IdValidator : AbstractValidator<IHasId>
{
    public IdValidator(Action whenValid)
    {
        RuleFor(x => x.Id).Must(x => x > 10).DependentRules(whenValid);
    }
}
  • Вопрос задан
  • 50 просмотров
Решения вопроса 1
@OwDafuq Автор вопроса
Примерное решение - использовать расширения для валидации полей.
Как это примерно выглядит:
1) Создать расширения для нужных полей (можно передавать DbContext, UoW, etc...)
2) В каждом валидаторе просто вешать правило валидации для нужного поля
internal static class RuleExtensions
{
    public static IRuleBuilderOptions<T, int> ValidateId<T>(this IRuleBuilder<T, int> builder)
        where T : IHasId
    {
        return builder.Must((t, x) => t.Id > 5);
    }
}


И создаем валидатор:
class FirstTestValidator : AbstractValidator<FirstTest>
{
    public FirstTestValidator()
    {
        RuleFor(x => x.Id).ValidateId().DependentRules(() =>
        {
            RuleFor(x => x.Guid).NotEmpty();
        });
    }
}


Таким образом валидация для поля Guid будет проводиться только если пройдет валидация для Id.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
petermzg
@petermzg
Самый лучший программист
Значение в БД ищется на уровне бизнес логики.
А Fluent Validator для проверки корректности параметров запроса.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы