How to use DataAnnotations Validation

The use of DataAnnotations, has increased over the years, as many frameworks are using it more and more, (MVC, Silverlight, etc).

However if you need to perform validation within your application and it is not any known framework then can we still use DataAnnotations?

The answer is yes, I'll try and take you through how you can go about it.

First lets create a class that we are going to use:

[code language=C#]

    public class Contact
    {

        [Required]
        [RegularExpression(@"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*([,;]\s*\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)*", ErrorMessage = "Invalid email address")]
        public string Email { get; set; }

        [Required]
        [StringLength(20)]
        public string FirstName { get; set; }

        [Required]
        public string LastName { get; set; }

        [Range(10,30)]
        public int Age {get;set;}

        public string City { get; set; }   

    }

[/code]

All of these validations are standard and out of the box when using DataAnnotations.

Next we need to be able to hold the Error Information, so I've created a class called ErrorInfo

[code language=C#]

    public class ErrorInfo
    {
        public ErrorInfo(string propertyName, string errorMessage, object instance)
        {
            PropertyName = propertyName;
            ErrorMessage = errorMessage;
            Instance = instance;
        }

        public string PropertyName { get; set; }
        public string ErrorMessage { get; set; }
        public object Instance { get; set; }

    }

[/code]

Now the clever bit, the Validation Runner (this was kindly supplied by Steve Sanderson and his xVal)

[code language=C#]

 

    internal static class DataAnnotationsValidationRunner
    {
        public static IEnumerable<ErrorInfo> GetErrors(object instance)
        {
            return from prop in TypeDescriptor.GetProperties(instance).Cast<PropertyDescriptor>()
                   from attribute in prop.Attributes.OfType<ValidationAttribute>()
                   where !attribute.IsValid(prop.GetValue(instance))
                   select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(string.Empty), instance);
        }
    }
[/code]

So that is the hard work done, now lets check for validation:

[code language=C#]

     IEnumerable<ErrorInfo> errors = DataAnnotationsValidationRunner.GetErrors(contact);

[/code]

How easy is that?

Okay now lets pick things up, What I would like to do next is Validate the City, to be a city in the UK, something like this would be nice:

[code language=C#]

      [City(ValidCity="Gloucester")]
      public string City { get; set; }

[/code]

In order to do this you are going to have to generate your own Attribute which needs to be based on the ValidationAttribute, again this is quite simple

[code language=C#]

 

    public class CityAttribute : ValidationAttribute
    {
        public string ValidCity { get; set; }

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

            if (value.ToString() != ValidCity)
            {
                return false;
            }

            return true;
        }
    }

 

[/code]

So you now can generate your own custom validation attributes with your own business rules.

DataAnnotationsValidation.zip (11.78 kb)

blog comments powered by Disqus

About the author

You have probably figured out by now that my name is Bryan Avery (if not, please refer to your browser's address field).  Technology is more than a career to me - it is both a hobby and a passion.  I'm an ASP.NET/C# Developer at heart...

Month List