Conditional DataAnnotations in c#


This is something a bit weird, which maybe even, dare I say, a bug in the .net DataAnnotationsExtensions pack (Installable via NuGet). I decorated one of my class properties with an Email data annotation, because If the class had an email set, I wanted to ensure it was valid. I didn’t, however, decorate it with a Required attribute. However it seems the Email attribute will return false if no value is passed, ensuring that it is infact required? (Please leave a comment if there is some really obvious built in way around this!)

To get around this I created a simple “IfPresent” data annotation which you can chain another validation onto; This basically returns a true if the value is null, otherwise it will pass it on to the real ValidationAttribute to work it”s magic. It can be implemented like this;

[DataMember]
[IfPresent(typeof(EmailAttribute), ErrorMessage = "Must be a valid email address")]
public string EmailAddress { get; set; }

The code is;

namespace Chinook.Model.ValidationAttributes
{
    public class IfPresent : ValidationAttribute
    {
        private ValidationAttribute attr;

        public IfPresent(Type attr)
        {
            this.attr = (ValidationAttribute)Activator.CreateInstance(attr); 
        }

        public override bool IsValid(object value)
        {
            if (value == null)
                return true;

            return attr.IsValid(value);
        }
    }
}
  1. #1 by Gareth on September 16, 2011 - 09:11

    I think this is a bug in these DataAnnotations?

    Do you have the code behind for the EmailAttribute?

    PS – That Elusive “Chinook” again! :)

  2. #2 by Gareth on September 16, 2011 - 09:55

    I had a look on their website for the online example and the HTML is:

    Email

    There is the data-val-email which i think is created by the “Required” attribute.

    Debug also the jquery.validate.js which validates the metadata passed from models :)

  3. #3 by Gareth on September 16, 2011 - 09:56

    Sorry the HTML is:

    ” Email

  4. #4 by Gareth on September 16, 2011 - 09:58

    See my Gmail for HTML!

  5. #5 by Shawson on September 19, 2011 - 08:30

    Ah yes, but the html5 and jquery.validate stuff is client side enforced validation- i’m talking about validating the data model on the server side!

  6. #6 by Gareth on September 19, 2011 - 16:56

    Mnnnnn – we need the code behind for these Annotations me thinks

  7. #7 by Shawson on September 21, 2011 - 11:03

    lol Gareth! This is the code behind!!

    The second snippet is it’s own self contained class- so would sit by itself in a file called IfPresentAnnotation.cs whereas the first snippet would be part of one of your model classes, and is an example of where the annotation is actually used, you see?

  8. #8 by Gareth on September 22, 2011 - 10:23

    Sorry im confuzzed. You wrote the IfPresentAnnotation didnt you?
    The code behind i mean is for the EmailAttribute itself, as this is the annotation which is throwing the error???

    Im confuzzed now!!

(will not be published)