Search code examples
c#.netblazorfluentvalidationfluentvalidation-2.0

How to access another model property in fluent validation when writing a certain model validator?


I cannot find enough documentation regarding a particular scenario.

Lets says I have a model Person.cs and has a property Salary.

I have to write a validator for this Salary property but it is dependent on another property from another Model named Department.

How do I access this property from another model?


Solution

  • You need a view model, with both the models, and a validator for it. Example:

        public class Person
        {
            public int Id { get; set; }
            public string? Name { get; set; }
            public decimal Salary { get; set; }
            public int Age { get; set; }
            public int DepartmentId { get; set; }
            public Department Department { get; set; }
        }
    
        public class Department
        {
            public int Id { get; set; }
            public string? Name { get; set; }
            public decimal BaseSalary { get; set; }
            public decimal SeniorSalary { get; set; }
        }
    
    
        public class ViewModel
        {
            public Person Person { get; set; }
            public List<Department> Departments { get; set; }
        }
    
        public class ViewModelValidator : AbstractValidator<ViewModel>
        {
            public ViewModelValidator()
            {
                RuleFor(x => x.Person).NotNull();
                RuleFor(x => x.Person.Name).NotEmpty();
                RuleFor(x => x.Person.Salary).GreaterThan(0);
                RuleFor(x => x.Person.DepartmentId).GreaterThan(0);
    
                RuleFor(x => x.Person.Department).NotNull();
    
                RuleFor(x => x.Person.Salary)
                    .GreaterThan(x => x.Person.Department != null ?            
                    x.Person.Department.BaseSalary : 0);
                When(w => w.Person.Age > 40 
                          && w.Person.Department != null
                          && w.Person.Department.SeniorSalary > 0, () =>
                {
                    RuleFor(x => x.Person.Salary).GreaterThan(x =>               
                            x.Person.Department.SeniorSalary);
                });
            }
        }
    

    In this example you have a form with the fields Name, Age, Salary and Department (combox box with Departments to choose from).

    The validator check if the Salary is greater than the Base Salary in the Department chosen.

    When you choose a Department with a Senior Salary greater than zero and the Person is 40 years old or older, the validator check for this field.

    Additional Info For the validation process you DON'T need the viewmodel with both Person and Department model. I've added both model because you probably need them together in a form.