Modal Validation(C#)

Modal Validation(C#)

Using MVC and viewmodel with MVC, modal validation is provided by framework itself and we can just do Modal.IsValid for checking if model is valid.

But what if we are not using Model Validation but still want a generic solution like that, at least similar and robust one, so here it goes:

public interface IDomainObject { }

IDomainObject is just a marker Interface to mark objects as Domain Object, also acts as a placeholder where ever Domain objects are expected.

class Person: IDomainObject
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

Given above is the actual domain model i.e Person. Also it gets inherited from IDomainObject just to mark Person as Domain Object.

public class PersonValidator:Validator<Person>
    {
        public PersonValidator(Person person)
        {
            Add(new BusinessRule<Person>(person, "Name","Name is required"), new ValidateLength());
        }
    }

Now that we have domain model, above given is the PersonValidator class that takes Person as an input and adds business rules(information about field, message to validate) and also Type of validation i.e ValidateLength.

   public class Validator<T>
        {
       public List<string> errors = new List<string>();
        Dictionary<BusinessRule<T>, IValidation> validators = new Dictionary<BusinessRule<T>, IValidation>();
        public void Add(BusinessRule<T> rule, IValidation validator) {
            validators.Add(rule, validator);
        }

        public bool Validate() {
            foreach (var validate in validators) {
                if (!validate.Value.IsValid<T>(validate.Key.domainObject , validate.Key.PropertyName)) {
                    errors.Add(validate.Key.ErrorMessage);
                }
            }
            return errors.Count>0?false:true;
        }
        }

As you might have seen PersonValidator gets inherited by Validator<T>, so above class is the generic Validator class that stores all the business rules as well as validator respectively.This class provides actual information about Domain model validation.

public  interface IValidation {
         bool IsValid<T>(T t,string property);
    }

Every validator inherits this above interface and checks if particular property of domain model is valid or not.

 public  class BusinessRule<T>
    {
        public string ErrorMessage { get; private set; }
        public string PropertyName { get; private set; }
        public T domainObject;
        public BusinessRule(T t, string propertyName , string errorMessage)
        {
            domainObject=t;
            ErrorMessage = errorMessage;
            PropertyName = propertyName;
        }
     }

This class will be used to actually hold Rules to validate particular domain model.This class will be used by validator to check validation.

 public abstract class Validation: IValidation
    {
        public abstract bool IsValid<T>(T t, string property);
        public Object GetObjValue<T>(T t, string property) {
            var prop = typeof(T).GetProperty(property);
            var value = prop.GetValue(t, null);
            return value;
        }
    }

Above is the abstract class that inherits IValidation and also gets inherited by every validator.Below is the example of such Validator:

 public class ValidateLength: Validation
    {
        public override bool IsValid<T>(T t, string property) {
            string value = GetObjValue(t, property).ToString();
            return value.Length > 0 ? true : false;
        }
    }

Now i think we have all the necessary components. So lets call vaildator and see if we get some validation errors:

var person = new Person() { Name = "" };
 var validator = new PersonValidator(person);
 if (!validator.Validate())
 {
     var errors = validator.errors;
 }

Incase of invalid domain model, you should be getting false while checking validator.Validate() and get some errors as well.