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 IEnumerableGetClientValidationRules(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.