Data Validation in MVC

If you work in MVC you will observe that all the model validation is attribute-based. In the past few days I have been working on a website architecture developed in ASP.NET 4.0 where I implemented attribute-based validation of a Data Model. To make the article simple I will explain it here using a console application with simple code. Let's start with a data model class:

  1. public class Model  
  2. {  
  3.     public string JobName { getset; }  
  4.     public string DeptName { getset; }  
  5.     public string EmpName { getset; }  

Here the requirement is that the Job Name Is mandatory and Dept Name is mandatory and its maximum length cannot be greater than 3 . A very obvious way to do it is to check all the conditions using IF-ELSE but It will increase the line of codes one needs to put IF – ELSE everywhere in the model class. To simplify it let's make two custom attributes that will validate the data model.

  1. [AttributeUsage(AttributeTargets.Field|AttributeTargets.Property)]  
  2.     public class Requierd:Attribute  
  3.     {  
  4.         public string ErrorMessage { getset; }  
  5.         public Requierd(string errorMessage)  
  6.         {  
  7.             this.ErrorMessage = errorMessage;  
  8.         }  
  9.             }  
  10.     [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]  
  11.     public class MaxLength : Attribute  
  12.     {  
  13.         public string ErrorMessage { getset; }  
  14.         public int Length { getset; }  
  15.         public MaxLength(string errorMessage,int MaximumLength)  
  16.         {  
  17.             this.ErrorMessage = errorMessage;  
  18.             this.Length = MaximumLength;  
  19.         }  
  20.    } 

Now we need one more class that will read the property value, validate it and show the Error message through Reflection.

  1. public class EntityBase  
  2. {  
  3.     public List<string> BrokenRules = null;  
  4.     public EntityBase()  
  5.     {  
  6.         BrokenRules = new List<string>();  
  7.     }   
  8.     public bool Validate()  
  9.     {  
  10.         bool IsValid = true;  
  11.         PropertyInfo[] PropInfo = this.GetType().GetProperties();  
  12.         foreach (PropertyInfo info in PropInfo)  
  13.         {  
  14.             object data = info.GetValue(thisnull);  
  15.   
  16.             foreach (object RequiredAttribute in info.GetCustomAttributes(typeof(Requierd), true))  
  17.             {  
  18.                 if (data == null)  
  19.                 {  
  20.                     IsValid = false;  
  21.                     BrokenRules.Add((RequiredAttribute as Requierd).ErrorMessage);  
  22.                 }   
  23.             }  
  24.             foreach (object MaxLengthAttribute in info.GetCustomAttributes(typeof(MaxLength), true))  
  25.             {  
  26.                 if (data != null)  
  27.                 {  
  28.                      if (data.ToString().Length > (MaxLengthAttribute as MaxLength).Length)  
  29.                      {  
  30.                          IsValid = false;  
  31.                          BrokenRules.Add((MaxLengthAttribute as MaxLength).ErrorMessage.ToString());  
  32.   
  33.                     }  
  34.                 }   
  35.              }  
  36.          }  
  37.          return IsValid;  
  38.      }  

Until now our Validation Attribute is ready, The Entity Base class is ready to validate . Let's return to the model class where we will implement it.

  1. public class Model : EntityBase  
  2. {  
  3.     [Requierd("Job Name Is Requierd")]  
  4.     public string JobName { getset; }   
  5.     [Requierd("DeptName Is Requierd")]  
  6.     [MaxLength("DeptName should not be greater than 3",3)]  
  7.     public string DeptName { getset; }   
  8.     public string EmpName { getset; }          

Time to initialize the model class from the Main class and call the validation function.

  1. static void Main(string[] args)  
  2. {   
  3.     Model obj = new Model();  
  4.     obj.JobName = "Coder";  
  5.     obj.DeptName = "Computer Science";  
  6.     if (!obj.Validate())  
  7.     {  
  8.         foreach (string message in obj.BrokenRules)  
  9.         {  
  10.            Console.WriteLine(message);  
  11.         }  
  12.     }  
  13.     Console.Read();  

In the Model class we have put the required attribute on JobName and DeptName and MaxLength attribute with max Length of 3 on Dept name, the Required attribute will successfully pass through but the Max Length Validation will fail because the length of Computer Science is more than 3.