Search code examples
asp.net-mvcasp.net-mvc-2-validationasp.net-mvc-3custom-validators

custom validation attribute not working on client, just on server


I am trying to implement custom attribute validation, similar to one demonstrated here in ScottGu's blog: http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx

I have this custom validator attribute for Email:

public class EmailAttribute : RegularExpressionAttribute
      {
      public EmailAttribute() :
                base("^[A-Za-z0-9](([_\\.\\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\\.\\-]?[a-zA-Z0-9]+)*)\\.([A-Za-z]{2,})$") { }
      }

My class uses it like this:

    [Required(ErrorMessage = ValidationCiM.MsgObaveznoPolje)]
    [Email(ErrorMessage = ValidationCiM.MsgMailNeispravan)]
    [StringLength(ValidationCiM.LenSrednjePolje, ErrorMessage = ValidationCiM.MsgSrednjePolje)]
    public string Mail { get; set; }

and it all works well on server side, model is validated ok, and everything. But client side validation does not activate for this the second attribute, it works for Required, and it also works for StringLength but not for Email. i have tried including both jquery and Microsoft ajax scripts, but there seems to be no difference.

In ScottGu's blog, he states that the custom validation if implemented like this should work without the need to add custom script.

Any ideas please?


Solution

  • Use IClientValidatable in ASP.NET MVC 3:

     public class EmailAttribute : RegularExpressionAttribute, IClientValidatable
    {
        public EmailAttribute()
          :base(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})$")
        {
    
        }
    
        public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
          var rule = new ModelClientValidationRegexRule(this.ErrorMessageString, base.Pattern);
          return new[] { rule };
        }
      }