Search code examples
c#.netfluentvalidation

Validate one list item is present in another list


I've got a model that looks like this:

public class ValidationModel
{
    public List<string> ValidNames;
    public List<Child> Children;
}

public class Child
{
    public string Name;
    public int Age;
}

I'm trying to write a fluent validator that will validate the ValidationModel class, and iterate around each child object in the Children collection and check to see if that value is present in the ValidationModel ValidNames collection.

public class MyValidator : AbstractValidator<ValidationModel>
{
    public MyValidator()
    {
        RuleForEach(o => o.Children).ChildRules(row =>
        {
            row.RuleFor(o => o.Name).IsPresentInValidNames()
        });
    }
}

How can I access the ValidNames collection in a rule shaped like the above? I basically want to do a contains on the ValidNames for each child in the Children collection.


Solution

    1. Create a ChildValidator with a constructor expecting a validNames array. With the help of System.Linq library, use IEnumerable<T>.Contains(T) to validate that the Name must be existed in the validNames array.
    using System.Linq;
    
    public class ChildValidator : AbstractValidator<Child>
    {
        public ChildValidator(List<string> validNames)
        {
            RuleFor(o => o.Name)
                .Must(x => validNames.Contains(x))
                .WithMessage("Name does not exist in ValidNames");
        }
    }
    
    1. After RuleForEach(o => o.Children), set the validator instance new ChildValidator(x.ValidNames) by passing the ValidNames array via SetValidator().
    public class MyValidator : AbstractValidator<ValidationModel>
    {
        public MyValidator()
        {
            RuleForEach(o => o.Children)
                .SetValidator(x => new ChildValidator(x.ValidNames));
        }
    }
    

    Demo @ .NET Fiddle