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 08:48

trackback

Property Matching With Data Annotations

Thank you for submitting this cool story - Trackback from DotNetShoutout

DotNetShoutout

January 7. 2010 08:50

trackback

Property Matching With Data Annotations

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

DotNetKicks.com

January 22. 2010 06: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 10: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 30. 2010 20:01

buenos aires travel guide

It could be great if we can comprare properties!

buenos aires travel guide

February 6. 2010 15: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 25. 2010 22: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 01: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 11:39

ucvhost

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

ucvhost

March 5. 2010 22:02

Fred Perry

I do learn a lot from this blog.

Fred Perry

March 7. 2010 21: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

March 13. 2010 15:01

mod converter

I happy to find many good point here,

mod converter

March 13. 2010 15:25

range hood

thank you for the post.
We see more kitchen hoods here.  

range hood

March 13. 2010 15:26

range hood

thank you for the post.
We see more kitchen hoods here.  

range hood

March 13. 2010 15:27

range hood

thank you for the post.
We see more kitchen hoods here.  

range hood

Add comment



(Will show your Gravatar icon)



 
Are you human? number1 + number0 =