Доступ к Parent DisplayName в CustomValidator в FluentValidation

У меня есть ViewModel (BarViewModel) с несколькими свойствами (Owner, Customer) типа Person. Я хочу, чтобы один пользовательский валидатор (PersonValidator) проверял эти свойства. Я хочу получить доступ к DisplayAttribute этих Person свойств в пользовательском валидаторе. Но я получаю null в результате для PropertyName, если я использую пользовательский валидатор, но не если я использую проверку непосредственно в BarViewModelValidator. Как я могу получить доступ к DisplayAttribute в моем пользовательском валидаторе?

Результат для переменной errors:

" должен быть старше 18 лет. (Детский валидатор)"

«Клиент должен быть старше 18 лет. (Родительский валидатор)»

[TestFixture]
public class BarViewModelTests
{
    public class BarViewModel
    {
        [Display(Name = "Owner of bar")]
        public Person Owner { get; set; } = new Person();

        [Display(Name = "A Customer")]
        public Person Customer { get; set; } = new Person();
    }

    public class Person
    {
        public int Age { get; set; }
    }

    public class PersonValidator : AbstractValidator<Person>
    {
        public PersonValidator()
        {
            RuleFor(p => p).Custom((_, context) =>
            {
                if ((context.InstanceToValidate as Person)!.Age < 18)
                {
                    context.AddFailure($"{context.PropertyName}.{nameof(Person.Age)}", $"{context.DisplayName} must be over 18 years. (Child Validator)");
                }
            });
        }
    }

    public class BarViewModelValidator : AbstractValidator<BarViewModel>
    {
        public BarViewModelValidator()
        {
            RuleFor(p => p.Owner).SetValidator(new PersonValidator());
            RuleFor(p => p.Customer).SetValidator(new PersonValidator());

            RuleFor(p => p.Customer).Custom((_, context) =>
            {
                if ((context.InstanceToValidate as BarViewModel)!.Customer.Age < 18)
                {
                    context.AddFailure($"{context.PropertyName}.{nameof(Person.Age)}", $"{context.DisplayName} must be over 18 years. (Parent Validator)");
                }
            });
        }
    }

    private BarViewModelValidator _validator;

    [SetUp]
    public void Setup()
    {
        _validator = new BarViewModelValidator();
    }

    [Test]
    public void Should_have_proper_display_name()
    {
        var model = new BarViewModel
        {
            Owner = new Person
            {
                Age = 20
            },
            Customer = new Person
            {
                Age = 15
            }
        };

        var errors = _validator.TestValidate(model).Errors;
    }
}

Я знаю, что это сработает, но я не хочу решать проблему так:

public class PersonValidator : AbstractValidator<Person>
    {
        public PersonValidator(string displayName)
        {
            RuleFor(p => p).Custom((_, context) =>
            {
                if ((context.InstanceToValidate as Person)!.Age < 18)
                {
                    context.AddFailure($"{context.PropertyName}.{nameof(Person.Age)}", $"{displayName} must be over 18 years. (Child Validator)");
                }
            });
        }
    }

    public class BarViewModelValidator : AbstractValidator<BarViewModel>
    {
        public BarViewModelValidator()
        {
            RuleFor(p => p.Owner).SetValidator(new PersonValidator("Owner of bar"));
            RuleFor(p => p.Customer).SetValidator(new PersonValidator("A Customer"));
        }
    }
Почему в Python есть оператор &quot;pass&quot;?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
1
0
549
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Дочерние валидаторы не знают о родительском валидаторе, поэтому они не могут получить доступ к имени родительского свойства таким образом. Итак, осталось три варианта:

  • чтобы явно передать его через конструктор и использовать SetValidator()
  • чтобы определить дочерние правила непосредственно внутри родительского валидатора
  • вместо этого определить расширение и использовать его аналогично дочернему валидатору

Другие вопросы по теме