How do I use the ComparisonRule when using DataAnnotations

Jun 5, 2009 at 7:03 PM

Hi,

I am using xVal with DataAnnotations on the server side and jquery on the client side. Unfortuantely there is no DataAnnotations comparison validation attribute  that would compare two properties of a ViewModel entity.

For the server side validation I can derive my own custom attribute from ValidationAttribute and add it to the ViewModel class instead of a specific property, but that doesn't seem to do anything useful on the client side.

Is there any easy way to make use of the ComparisonRule so that I also get client-side validation? Any sample code would be greatly appreciated.

Thanks,

Adrian

Coordinator
Jun 18, 2009 at 10:37 PM

Hi Adrian

It's tricky to do comparisons with DataAnnotations on the server side, because the DataAnnotations API only lets you validate the value of a specific field, and doesn't give you access to the other fields in any useful way so you can compare them.

However, the client side bit is possible with xVal because you can implement a custom rule:

 

    public class ValidatePropertyEqualityAttribute : Attribute
    {
        public ValidatePropertyEqualityAttribute(string propertyA, string propertyB)
        {
            PropertyA = propertyA;
            PropertyB = propertyB;
        }

        public string PropertyA { get; set; }
        public string PropertyB { get; set; }
    }

Next, you'll need a rule provider that can recognize this:

 

    public class MyCustomRulesProvider : CachingRulesProvider
    {
        protected override RuleSet GetRulesFromTypeCore(Type type)
        {
            var comparisonRules = type.GetCustomAttributes(typeof (ValidatePropertyEqualityAttribute), true).Cast<ValidatePropertyEqualityAttribute>();
            return new RuleSet(comparisonRules.ToLookup(x => x.PropertyB, x => (Rule)new ComparisonRule(x.PropertyA, ComparisonRule.Operator.Equals)));
        }
    }

... and register your custom rule provider in Global.asax.cs:

 

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
        ActiveRuleProviders.Providers.Add(new MyCustomRulesProvider());
    }

With this in place, you can attach [ValidatePropertyEquality] to a model class:

 

    [ValidatePropertyEquality("Name", "NameRepeat")]
    public partial class Booking
    {
        public string Name { get; set; }        
        public string NameRepeat { get; set; }
        // ... etc
    }

This will take care of client-side validation. Your message indicates you're able to take care of server-side validation so I'll leave it there!

Steve

Jun 20, 2009 at 9:02 AM

Hi Steve,

Thanks for your reply. I am aware of custom rules, but was hoping that there is a generic way to implement using without writing separate code for client and server side. It still helps to know that there is none though.

Adrian

Jun 25, 2009 at 12:15 PM

Hi Steve,

Could you please provide the code snippet for the server side validation ?

Great job indeed.....

Thanks

 

 

Aug 27, 2009 at 9:07 PM

Hi,

I am having the same problem and would like to see what the server side validation looks like.

 

Thanks.