Complex Custom Validation Attribute Specific to Entity

System.Componentmodel.DataAnnotation is a namespace in the .Net Framework that provides a set of attribute classes. These attribute classes decorate a property of the user-defined entity and validates the entity.

To see more about each class go to the MSDN at https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations%28v=vs.95%29.aspx.

ValidationAttribute

Most of the required attributes for validation are provided in the DataAnnotation namespace but there are some complex validations required to validate an entity that must be defined by the developer themself.

ValidationAttribute is a class in the DataAnnotation namespace that allows creaton of a custom attribute depending on the needs of the developer to validate the entity.

The following is an implementation of the custom validation attribute:

  1. [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]  
  2. public sealed class AccountBalaceCheckAttribute : ValidationAttribute  
  3. {  
  4.         protected override ValidationResult IsValid(object value, ValidationContext validationContext)  
  5.         {  
  6.             ValidationResult result = ValidationResult.Success;  
  7.             string[] memberNames = new string[] { validationContext.MemberName };  
  8.   
  9.             decimal val = Convert.ToDecimal(value);  
  10.   
  11.             BankAccount account = (BankAccount)validationContext.ObjectInstance;  
  12.   
  13.             if (account.AcType == BankAccount.AccountType.Saving && val < 500)  
  14.                 result = new ValidationResult(string.Format(this.ErrorMessage, 500),memberNames);  
  15.             else if (account.AcType == BankAccount.AccountType.Current && val < 1000)  
  16.                 result = new ValidationResult(string.Format(this.ErrorMessage, 1000), memberNames);  
  17.   
  18.   
  19.             return result;  
  20.         }  

The following shows how to use it:

  1. public class BankAccount  
  2. {  
  3.   
  4.    public enum AccountType  
  5.    {  
  6.       Saving,  
  7.       Current  
  8.    }  
  9.   
  10.    public AccountType AcType { getset; }  
  11.   
  12.    [AccountBalaceCheckAttribute(ErrorMessage = "Account Balance should have value more than {0}")]  
  13.    public double AccountBalance { getset; }  

In this example the attribute is defined for the specific entity BankAccount entity. The requirement for defining this attribute are “Based on the value of AccountType, the account should hold the minimum balance.”.

So for that here, the BankAccount object is accessed in the IsValid method and then by checking the value of the Account type attribute it validates the AccountBalance value.

The following are other things to note here:

  1. The Attribute class is Sealed and Derived from the ValidationAttribute.
  2. The custom attribute class overrides the IsValid method of the base ValidationAttribute class.
  3. The attribute can be used for a property and not allowed to define an attribute multiple times on the property.

To see how to define an attribute not specific to an entity go to the MSDN at https://msdn.microsoft.com/en-us/library/cc668224%28v=vs.140%29.aspx.