MVC Validations 4: Whole class business object attribute validations

Sometimes you need to validate an object where the column data itself isn’t enough to determine if the object is valid from a business perspective. However, this doesn’t mean you have to abandon attributes for validation!

As an example say we have this class:

public class BusinessObject
{
    public int PropA { get; set; }
    public int PropB { get; set; }
    public int PropC { get; set; }
}

Our BusinessObject class here, say it’s only valid if the three properties have a sum of 100. Obviously we can’t set max and min values on the properties themselves to achieve this. What we need is an annotation attachable to the class itself. It works like this:

[AttributeUsage(AttributeTargets.Class)]
    public class NumberSumAttribute : ValidationAttribute
    {
        public override bool IsValid(object value)
        {
            var businessObject = value as BusinessObject;
            if (businessObject == null)
            {
                throw new ArgumentException("This annotation is not attachable to this object class");
            }
            return businessObject.PropA + businessObject.PropB + businessObject.PropC == 100;
        }
    }

Attach it to the head of your class like this

[NumberSumAttribute(ErrorMessage = "All fields must add up to 100.")]
public class BusinessObject
{
    public int PropA { get; set; }
    public int PropB { get; set; }
    public int PropC { get; set; }
}

That’s pretty much it. An obvious sticking point here is the class cast, but as far as I know I cannot restrict the validation attribute to only being applyable to some types. It’s possible to achieve this in some fashion by fidding around with access restrictions and inheritance like this if you really think you need this compile time security.

Oh, and since you won’t get the validation message on a field anymore you’ll need to stick the class generic validation messages somewhere. Add @Html.ValidationSummary(true) where you want these messages to appear, and you’re good to go!

Advertisements
Tagged , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: