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 { get; set; }
  4. public string DeptName { get; set; }
  5. public string EmpName { get; set; }
  6. }

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 { get; set; }
  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 { get; set; }
  14. public int Length { get; set; }
  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(this, null);
  15. foreach (object RequiredAttribute in info.GetCustomAttributes(typeof(Requierd), true))
  16. {
  17. if (data == null)
  18. {
  19. IsValid = false;
  20. BrokenRules.Add((RequiredAttribute as Requierd).ErrorMessage);
  21. }
  22. }
  23. foreach (object MaxLengthAttribute in info.GetCustomAttributes(typeof(MaxLength), true))
  24. {
  25. if (data != null)
  26. {
  27. if (data.ToString().Length > (MaxLengthAttribute as MaxLength).Length)
  28. {
  29. IsValid = false;
  30. BrokenRules.Add((MaxLengthAttribute as MaxLength).ErrorMessage.ToString());
  31. }
  32. }
  33. }
  34. }
  35. return IsValid;
  36. }
  37. }

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 { get; set; }
  5. [Requierd("DeptName Is Requierd")]
  6. [MaxLength("DeptName should not be greater than 3",3)]
  7. public string DeptName { get; set; }
  8. public string EmpName { get; set; }
  9. }

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();
  14. }

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.