Ajit Goel
Ajit Goel

Reputation: 4418

Check a property is unique in list in FluentValidation

I am trying to ensure that a list has unique SSN's. I am getting the "Property name could not be automatically determined for expression element => element. Please specify either a custom property name by calling 'WithName'" error. Would we know what I am doing wrong here?

    using FluentValidation;
    using FluentValidation.Validators;

    public class PersonsValidator : AbstractValidator<Persons>    
    {
        public PersonsValidator()
        {
            this.RuleFor(element => element)
               .SetValidator(new SSNNumbersInHouseHoldShouldBeUnique<Persons>())
.WithName("SSN");
                .WithMessage("SSN's in household should be unique");
        }
    }

    public class SSNNumbersInHouseHoldShouldBeUnique<T> : PropertyValidator
    {
        public SSNNumbersInHouseHoldShouldBeUnique()
        : base("SSN's in household should be unique")
        {
        }

        protected override bool IsValid(PropertyValidatorContext context)
        {
            var persons = context.Instance as Persons;
            try
            {
                if (persons == null)
                {
                    return false;
                }

                var persons = persons.Where(element => element.SSN.Trim().Length > 0);
                var allSSNs = persons.Select(element => element.SSN.Trim());
                if (allSSNs.Count() > allSSNs.Distinct().Count())
                {
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }

    public class Persons : List<Person>
    {}

    public class Person
    {
        public string SSN{ get; set; }
    }

Upvotes: 2

Views: 6147

Answers (1)

Ajit Goel
Ajit Goel

Reputation: 4418

I was using FluentValidation version 4.6. According to Jeremy Skinner(author of FluentValidation), I need to be on at least 5.6 to be able to use model-level rules (like RuleFor(element => element)). As a workaround, I added this validation on the actual class itself instead of creating a validation class. Hope this helps someone.

using FluentValidation;
using FluentValidation.Results;

 public class Persons : List<Person>
{
public void ValidateAndThrow()
        {
            var errors = new List<ValidationFailure>();
            try
            {
                var persons = this.Where(element => element.SSN.Trim().Length > 0);
                var allSSNs = persons.Select(element => element.SSN.Trim());
                if (allSSNs.Count() > allSSNs.Distinct().Count())
                {
                    var validationFailure = new ValidationFailure("UniqueSSNsInHouseHold", "SSN's in a household should be unique");
                    errors.Add(validationFailure);
                }         
            }
            catch (Exception ex)
            {
            }

            if (errors.Any())
            {
                throw new ValidationException(errors);
            }
        }
}

Upvotes: 3

Related Questions