Property Matching With Data Annotations

I found myself needing to compare two properties on a view model when developing a new ASP.NET MVC 2.0 site today. My initial thoughts were I would check the two properties for equality by making a call to my business logic assembly.

I wondered if it would be possible to compare two properties using data annotations. Usually you place the data annotations attribute on a property to validate the data in some way. I quickly knocked up a custom ValdationAttribute that could be placed on a class that checks for equality between two properties of the class. It checks both type and value equality.

using System;
using System.ComponentModel.DataAnnotations;
using System.Reflection;

namespace Model.CustomAnnotations
{
    [AttributeUsage(AttributeTargets.Class)]
    public class MatchAttribute : ValidationAttribute
    {
        public String SourceProperty { get; set; }
        public String MatchProperty { get; set; }

        public MatchAttribute(string source, string match)
        {
            SourceProperty = source;
            MatchProperty = match;
        }

        public override Boolean IsValid(Object value)
        {
            Type objectType = value.GetType();

            PropertyInfo[] properties = objectType.GetProperties();

            object sourceValue = new object();
            object matchValue = new object();

            Type sourceType = null;
            Type matchType = null;

            int counter = 0;

            foreach (PropertyInfo propertyInfo in properties)
            {
                if (propertyInfo.Name == SourceProperty || propertyInfo.Name == MatchProperty)
                {
                    if (counter == 0)
                    {
                        sourceValue = propertyInfo.GetValue(value, null);
                        sourceType = propertyInfo.GetValue(value, null).GetType();
                    }
                    if (counter == 1)
                    {
                        matchValue = propertyInfo.GetValue(value, null);
                        matchType = propertyInfo.GetValue(value, null).GetType();
                    }
                    counter++;
                    if (counter == 2)
                    {
                        break;
                    }
                }
            }

            if (sourceType != null && matchType != null)
            {
                if (Convert.ChangeType(sourceValue, sourceType) == Convert.ChangeType(matchValue, matchType))
                    return true;
            }
            return false;
        }
    }
}

Here is how the attribute is placed on a class. The attribute takes two values which are the names of the properties you need to match.

    [Match("Email", "EmailConfirmation", ErrorMessage = "Emails must match")]
    public class PersonViewModel
    {
        public int PersonId { get; set; }
        [Required]
        public string Firstname { get; set; }
        [Required]
        public string Lastname { get; set; }
        [Required]
        public string Email { get; set; }
        [Required]
        public string EmailConfirmation { get; set; }
    }

This then bubbles up to the UI. If you are using MVC 2.0 this will work out of the box as the default model binder supports data annotations.

Pretty straight forward but very useful! You can download the code here to see it working end to end. You will need MVC 2.0 RC installed as well as Visual Studio Standard Edition or above.

Twitter Twitter Twitter Twitter Twitter
January 9, 2010 14:04 by DanWatson

Comments

January 7. 2010 13:48

trackback

Property Matching With Data Annotations

Thank you for submitting this cool story - Trackback from DotNetShoutout

DotNetShoutout

January 7. 2010 13:50

trackback

Property Matching With Data Annotations

You've been kicked (a good thing) - Trackback from DotNetKicks.com

DotNetKicks.com

January 22. 2010 11:44

Caretaker Pools Parts

This article would be one of the ASP.net I used to know, thanks for sharing it with us. Hope you could make more articles that are useful and very interesting to everyone. Thanks a lot! Have a nice day!

Caretaker Pools Parts

January 25. 2010 15:15

Life Insurance Quotes

The values given above are very useful. This info surely help the reader. I appreciate the post very much. Thanks a lot for the post.

Life Insurance Quotes

January 31. 2010 01:01

buenos aires travel guide

It could be great if we can comprare properties!

buenos aires travel guide

February 6. 2010 20:34

nintendo ds r4

kindly send an sample project. How it works?How do you provide an error message when a user enters a string in a datetime field?


thanks in advance

nintendo ds r4

February 26. 2010 03:55

forex vps

his info surely help the reader. I appreciate the post very much. Thanks a lot for the post.

forex vps

March 3. 2010 06:19

make iphone ringtone

Really its a good news. I am very interested for this post. This side will be help all of us. Thanks.

make iphone ringtone

March 3. 2010 16:39

ucvhost

I am very interested for this post. This side will be help all of us. Thanks

ucvhost

March 6. 2010 03:02

Fred Perry

I do learn a lot from this blog.

Fred Perry

March 8. 2010 02:47

Swarovski bead suppliers

The code is very useful, but taking me a bit of time to get to grips with as ASP is fairly new to me.

Swarovski bead suppliers

Add comment



(Will show your Gravatar icon)



 
Are you human? number5 + number7 =