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
}
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.