How to validate child objects by implementing IDataErrorInfo on parent class

raja9787 picture raja9787 · Jul 23, 2010 · Viewed 8.4k times · Source

I am developing a WPF Application using MVVM Architecture. I am an amateur in WPF so bear with me..

I have two model classes. Parent class has an object of another (child) class as its property. (i mean nested objects and not inherited objects)

For instance, consider the following scenario.

public class Company
{

   public string CompanyName {get; set;}

   public Employee EmployeeObj {get; set;}
}

public class Employee 
{

   public string FirstName {get; set;}

   public string LastName {get; set;}

}    

I want to validate the properties of Employee entity using Enterprise Library Validation Block.

I was able to do it by implementing IDataErroInfo interface in employee class as shown below

public class Employee :  IDataErrorInfo

{

   [NotNullValidator(MessageTemplate="First Name is mandatory"]
   public string FirstName {get; set;}

   [StringLengthValidator(0,20,MessageTemplate="Invalid")]
   public string LastName {get; set;}

   public string Error
   {
        get
        {
            StringBuilder error = new StringBuilder();

            ValidationResults results = Validation.ValidateFromAttributes<Employee>(this);

            foreach (ValidationResult result in results)
            {
                error.AppendLine(result.Message);
            }

            return error.ToString();
        }

    }

    public string this[string propertyName]
    {
        get
        {
            ValidationResults results = Validation.ValidateFromAttributes<Employee>(this);

            foreach (ValidationResult result in results)
            {
                if (result.Key == propertyName)
                {
                    return result.Message;
                }
            }

            return string.Empty;
        }
    }
}

I dont want to implement IDataErroInfo for every child model i create.

Is there any way to validate the Employee object by implementing IDataErrorInfo on the parent (Company) class ?

And also is there any triggers to start validation of objects. I would like to validate the objects only when i want to and not all the time.

Answer

Steven picture Steven · Nov 1, 2010

You can absolutely implement IDataErrorInfo on a base class using Validation Application Block. Here is an article that describes how to. The code basically comes down to this:

public abstract class DataErrorInfo : IDataErrorInfo
{
    string IDataErrorInfo.Error
    {
        get { return string.Empty; }
    }

    string IDataErrorInfo.this[string columnName]
    {
        get
        {
            var prop = this.GetType().GetProperty(columnName);
            return this.GetErrorInfo(prop); 
        }
    }

    private string GetErrorInfo(PropertyInfo prop)
    {
        var validator = this.GetPropertyValidator(prop);

        if (validator != null)
        {
           var results = validator.Validate(this);

           if (!results.IsValid)
           {
              return string.Join(" ",
                  results.Select(r => r.Message).ToArray());
           }
        }

        return string.Empty;
    }

    private Validator GetPropertyValidator(PropertyInfo prop)
    {
        string ruleset = string.Empty;
        var source = ValidationSpecificationSource.All;
        var builder = new ReflectionMemberValueAccessBuilder();
        return PropertyValidationFactory.GetPropertyValidator(
            this.GetType(), prop, ruleset, source, builder);
    }
}

You can use this abstract class add validation behavior to your entities by inheriting from it:

public partial class Customer : DataErrorInfo
{
}