Consider that we need to validate an instance of the Person class given below.
public class Contact
    {
        public string FirstName { get; set; } // Mandatory
        public string MiddleName { get; set; }
        public string LastName { get; set; } // Mandatory

        public string PersonalEmail { get; set; } // At least one of Personal or Business email is mandatory
        public string BusinessEmail { get; set; } 
        
        public Company Organization { get; set; }

        public Address BusinessAddress { get; set; } // Business address is mandatory if the person is currently working.
        public Address OtherAddress { get; set; }

        public Job CurrentJob { get; set; } // Current job is mandatory if the person is currently working.
    }

    public class Address
    {
        public string AddressLine1 { get; set; } // Mandatory
        public string AddressLine2 { get; set; } // Mandatory
        public string AddressLine3 { get; set; }
        public string AddressLine4 { get; set; }
        public string City { get; set; } // Mandatory
        public string StateOrCounty { get; set; }
        public string Country { get; set; } // Mandatory
        public string Zipcode { get; set; } // Mandatory
    }

    public class Company
    {
        public string Name { get; set; } // Mandatory
        public Address OfficeAddress { get; set; } // Mandatory
    }

    public class Job
    {
        public string Title { get; set; } // Mandatory
        public DateTime From { get; set; } // Mandatory
        public DateTime? To { get; set; } // Optional, should be greater than From
    }
  • Validating by writing a custom validator.
    public class ContactValidator
    {
        public virtual List<ValidationError> Validate(Contact contact)
        {
           // We will do a cross object validation on someOtherObject in Method 2 below
           var someOtherObject = new object();
            var validator = contact
                            .Validate(new ValidationOptions{StopOnFirstError = false})
                            .IsNotNullOrEmpty(c => c.FirstName, "First Name is mandatory.")
                            .IsNotNullOrEmpty(c => c.LastName, "Last Name is mandatory.")
                            // Method 1, using predicates
                            .Or("One of personal or business email is mandatory",
                                  c => !c.BusinessEmail.IsNullOrEmpty(),
                                  c => !c.PersonalEmail.IsNullOrEmpty(),
                                )
                            .IfThen(c => c.Organization != null, "Organization title and address are mandatory.",
                                         c => !c.Organization.Name.IsNullOrEmpty(),
                                         c => !c.Organization.OfficeAddress.AddressLine1.IsNullOrEmpty(),
                                         c => !c.Organization.OfficeAddress.AddressLine2.IsNullOrEmpty(),
                                         c => !c.Organization.OfficeAddress.City.IsNullOrEmpty(),
                                         c => !c.Organization.OfficeAddress.Country.IsNullOrEmpty(),
                                         c => !c.Organization.OfficeAddress.Zipcode.IsNullOrEmpty()
                                   )
                            // Method 2, using other validators
                            .IfThen(c => c.Organization != null, "Job details are incorrect",
                                       c => c.CurrentJob.Validate(new ValidationOptions{StopOnFirstError = false})
                                                .IsNotNullOrEmpty(j => j.Title, "Job title is mandatory")
                                                .IfThen(j => j.To.HasValue, "Job To date should be after job from date",
                                                        j => j.From > j.To
                                                       ),
                                        // Cross object validation
                                        c => someOtherObject.Validate().IsNotNull(o => o, "Some other object is null")
                                   )
                            // Method 3, using saved validation rules
                            // Assuming that we have saved a named validation for Address
                            .IfThen(c => c.Organization != null, "Office address is mandatory if person is currently working",
                                    c => c.BusinessAddress.ValidateUsing("Default_Address_Validation")
                                   );
            return validator.Errors.ToList();
        }
    }

We have used 3 distinct methods in our validator.
  • Method 1: This uses predicates and is useful when you have to validate one off validation rules which will not be reused.
  • Method 2: This uses other validators. These validators can be used on any other variable in scope and can be used to do validations across multiple objects.
  • Method 3: This uses a saved validation rule "DefaultAddressValidation" which we have set up for our Address class. This is easily reusable and can be used to do validations on a type which is a member of many different classes.

Last edited Jan 7, 2011 at 6:56 PM by ashishsharmaait, version 1

Comments

No comments yet.