Custom Validation Attribute in MVC
jlopez - Tue, 2016-04-12 10:15
Creating a custom validation attribute for that you can use as a Data Annotation on your models is not hard, but does require a bit of care to make it work on both the server and client side. The first step is to create a class that inherits from ValidationAttribute and implements IClientValidatable. In one project, we need to validate against US and UK phone numbers.
[AttributeUsage(AttributeTargets.Property |
AttributeTargets.Field |
AttributeTargets.Parameter, AllowMultiple = false)]
public class ValidPhoneAttribute : ValidationAttribute, IClientValidatable
From there, we implement the IsValid method:
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
ValidationResult validationResult = ValidationResult.Success;
string toValidate = (string)value;
if (!Parse.IsPhone(toValidate))
{
validationResult = new ValidationResult(ErrorMessageString);
}
return validationResult;
}
Finally, we implement IClientValidate. The "validphone" string defines the function in our javascript file that will be called.
public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
string errorMessage = ErrorMessageString;
// The value we set here are needed by the jQuery adapter
ModelClientValidationRule validPhoneRule = new ModelClientValidationRule()
{
ErrorMessage = errorMessage,
ValidationType = "validphone" /* This is the name the jQuery adapter will use*/
};
yield return validPhoneRule;
}
In our javascript library file custom-validation.js, we added
$.validator.addMethod("validphone", function (value, element, params) {
usPhoneRe = /^[(]?(\d{3})[) -\.]?[ ]?(\d{3})[ -\.]?(\d{4})$/;
ukPhoneRe = /^\+?44[ -\(\)\d]{9,}$/;
var isUsPhone;
isUsPhone = usPhoneRe.test(value);
var isUkPhone;
isUkPhone = ukPhoneRe.test(value);
return isUsPhone || isUkPhone;
});
$.validator.unobtrusive.adapters.add("validphone", function (options) {
options.rules["validphone"] = "#" + options.value;
options.messages["validphone"] = options.message;
});
This registers the method with the jquery validator object.
