# Wednesday, March 23, 2011
« Visual Studio 2010 - Silverlight 4 Tools... | Main | Required’s AllowEmptyString is ignored w... »

I’m working on the latest Entity Framework RC 4.1 that comes with Code First. In my quest I learned how the Data Annotations work on empty fields. Something I thought I knew but after being schooled by my simple MVC3 project I had a little help on twitter to set me straight.

I asked on twitter – Do Data Annotation validators run when the field is empty? Required does but my experiment on others don't seem to?

I mean, of course, duh, required would but it didn’t seem like the other validators were.  I was two validators.  The first was the String Length and I had set the Minumim and Maximum Length.  The other was the regular expression validator that wanted 4 digits.  When I emptied the fields, the validator appeared to not run because I didn’t get an error displayed.  If I entered a character then the validation appeared. 

What’s going on? It would make sense that for the String Length validator with a Minimum Length set that when nothing is entered it should fire right?  Clearly, we are below the minimum length.  I began to assume that the validators other than the Required didn’t run if the field is empty.  I always thought they did run. 

Well, @srkirkland to the rescue.  He set me straight.

@klabranche When a field is empty other vals will still run, just return valid always. Convention is non-required vals return true w/ null

…and @srkirkland would know, he runs the OSS Data Annotations Extensions project.

Convention is non-required validators will return true with nulls

I feel as though I should have known this but clearly I didn’t. Maybe, just maybe I had it way deep in the recesses of my mind. A lot of good that did me. :-) How about you?

For the purpose of this post let’s fire up reflector and see for ourselves!

regular expression annotation reflector code

All Data Annotations wield their magic in the IsValid method.  As you can see below the Regular Expression Annotation checks to see if the string coming in is null or empty and if it is return true.

public override bool IsValid(object value)
    string str = Convert.ToString(value, CultureInfo.CurrentCulture);
    if (string.IsNullOrEmpty(str))
        return true;
    Match match = this.Regex.Match(str);
    return ((match.Success && (match.Index == 0)) && (match.Length == str.Length));

How about one more? String Length

string length annotation reflector code 

public override bool IsValid(object value)
    int num = (value == null) ? 0 : ((string) value).Length;
    return ((value == null) || ((num >= this.MinimumLength) && (num <= this.MaximumLength)));

Again, you can see if the initial object coming in is null then return true.

Why this convention

I found a reference on Phil Haack’s blogs:


Notice that if the value is null, we return true. This attribute is not intended to validate required fields. I’ll defer to the RequiredAttribute to validate whether the value is required or not. This allows me to place this attribute on an optional value and not have it show an error when the user leaves the field blank.

Where I went wrong

Back to the String Length validator. If it would fire for an empty string then we are essentially making the String Length validator a required field validator also.  This may seem logical and was my assumption. In reality, if this was true we would be making the String validator also a required validator. Having the convention on all non-required validators return true when their field is empty ensures those validators are not forcing an implicit required.  How fun would that be for a field we wanted to ensure was a certain format but could also be empty?

So there you have it.  I was ready to blame Code First or the Entity Framework, surely not my own assumptions. :-)

Happy Coding!

Please login with either your OpenID above, or your details below.
(will show your gravatar icon)
Home page

Comment (Some html is allowed: b, blockquote@cite, em, i, strike) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

[Captcha]Enter the code shown (prevents robots):

Live Comment Preview