Home » ASP » ASP.MVC » Custom Validation Attribute for String with Underneath Property Validation

Custom Validation Attribute for String with Underneath Property Validation

Validation can occur with an attribute during client side and server side. For example, one simple validation can be to ensure that a property string is all to lower case. This can be a simple attribute like the following one.

/// <summary>
/// Validate that the string is in lower case
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class LowerCaseString : BaseDataAnnotation
{
	protected override ValidationResult IsValid(object value, ValidationContext validationContext)
	{
		string model = value as string;
		
		if (model != null)
		{
			if(string.Equals(model, model.ToLowerInvariant(), StringComparison.InvariantCulture))
			{
				return ValidationResult.Success;
			}
		}
		return base.ReturnDefaultErrorMessage(string.Format(Resources.DataAnnotationErrorMessage.StringNotLowerCase, validationContext.DisplayName)
												, new[] { validationContext.MemberName });
	}
}

WebValidationAttribute
This class works well but sometime you may want to have the validation to appears but validating a property of the class. For example, here is a class named StockOrder that use a problem called StockSymbol which must be in lower case and we want to validate the property of this class during validation. Adding the LowerCaseString attribute without specifying the property to check on the StockSymbol class does not allow the case to string inside the attribute. It crashes.

public class StockOrder 
{
	[Required]
	[LowerCaseString]
	[Display(ResourceType = typeof(ModelPropertyDisplayName), Name = "StockSymbol")]
	public Symbol StockSymbol { get; set; }	
}

You may think that you should set the LowerCaseString to the string property in the beneath property’s class. However, we cannot only set the attribute on the property class because the graphical user interface need to add the validation to the property and not the property of a property. To fix this problem, it is possible to add a property to the attribute with the goal of specifying the property to validate underneath.

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class LowerCaseString : BaseDataAnnotation
{
	public string InnerProperty { get; set; }
	protected override ValidationResult IsValid(object value, ValidationContext validationContext)
	{
		string model;
		if (value is string || String.IsNullOrEmpty(InnerProperty))
		{
			model = value as string;
		}
		else
		{
			Type thisType = value.GetType();
			PropertyInfo theMethod = thisType.GetProperty(InnerProperty);
			model = (string)theMethod.GetValue(value);
		}
		if (model != null)
		{
			if(string.Equals(model, model.ToLowerInvariant(), StringComparison.InvariantCulture))
			{
				return ValidationResult.Success;
			}
		}
		return base.ReturnDefaultErrorMessage(string.Format(Resources.DataAnnotationErrorMessage.StringNotLowerCase, validationContext.DisplayName)
												, new[] { validationContext.MemberName });
	}
}

The InnerProperty property is checked to see if set and if it is set on an attribute that is not a string than by reflection we get the property value and validate. The goal of verifying if the property is a string is for advanced scenario where the validation is done on a class on the Model and on a string on the ViewModel. This situation can occur if you are working with a Model-ViewModel architecture and that you transfer automatically with AutoMapper Data Annotation validation.

public class StockOrder 
{
	[Required]
	[LowerCaseString(InnerProperty = "Value")]
	[Display(ResourceType = typeof(ModelPropertyDisplayName), Name = "StockSymbol")]
	public Symbol StockSymbol { get; set; }	
}

At the end, what is important is that you can specify inside an attribute which property to validate and having the option to be more specific in some scenario.

If you like my article, think to buy my annual book, professionally edited by a proofreader. directly from me or on Amazon. I also wrote a TypeScript book called Holistic TypeScript

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.