21

To keep my model validation clean I would like to implement my own validation attributes, like PhoneNumberAttribute and EmailAttribute. Some of these can favorably be be implemented as simple classes that inherit from RegularExpressionAttribute.

However, I noticed that doing this breaks client side validation of these attributes. I am assuming that there is some kind of type binding that fails somewhere.

Any ideas what I can do to get client side validation working?

Code example:

public sealed class MailAddressAttribute : RegularExpressionAttribute
{
    public MailAddressAttribute()
        : base(@"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$")
    {
    }
}
KyleMit
  • 30,350
  • 66
  • 462
  • 664
zidar
  • 754
  • 2
  • 9
  • 19
  • But it is a RegularExpressionAttribute and it has a regular expression, which works just fine if it's explicitly defined in the model. – zidar Sep 02 '10 at 14:24
  • Exactly what I was about to ask – TWith2Sugars Sep 28 '10 at 08:51
  • Possible duplicate of [Custom DataAnnotations Validator Derived from RegularExpressionAttribute](https://stackoverflow.com/questions/2689444/custom-dataannotations-validator-derived-from-regularexpressionattribute) – KyleMit Apr 11 '19 at 18:54

2 Answers2

32

You'll need to register a client-side validation adapter for your custom attribute. In this case you can use the existing RegularExpressionAttributeAdapter in System.Web.Mvc, since it should work exactly the same as the standard regex attribute. Then register it when your application start using:

DataAnnotationsModelValidatorProvider.RegisterAdapter(
    typeof(MailAddressAttribute),
    typeof(RegularExpressionAttributeAdapter));

Should you write an attribute that requires custom client-side validation, you can implement your own adapter by inheriting from DataAnnotationsModelValidator (see also Phil Haack's blog).

Denilson Sá Maia
  • 47,466
  • 33
  • 109
  • 111
cjberg
  • 519
  • 4
  • 3
  • How to register adapter from the place where I defined attribute. This implementation requires knowing attributes. I can not pass DLL to another developer and ask to use attributes I should also ask him to add some code to his asax file. Is there more less coupled way? – Cherven Apr 05 '12 at 19:35
9

extending of the right answer

public class EmailAttribute : RegularExpressionAttribute
{
    static EmailAttribute()
    {
        DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(EmailAttribute), typeof(RegularExpressionAttributeAdapter));
    }

    public EmailAttribute()
        : base(@"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$") //^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$
    {

    }
}
Cherven
  • 1,101
  • 3
  • 17
  • 26
  • For some reason, even though the static constructor was being called, this was not generating the client side validation markup. So I added the registration to `Application_Start()`, in `Global.asax`. – Eric Lease Dec 15 '17 at 15:21