Uncategorized

Attribute for validating when at least one of many properties must be set

Here’s some code for a validation attribute that can be set on a class, when at least one property out of a couple must be set in order to pass validation. A great use for this is when you require either a home phone number or a cell phone number to be set, since you can’t expect all user to have a home phone number, and you can’t expect all users to have a cell phone number either, but you have to know whether it is a home or a cell number.

Enjoy!

///

/// Checks all the properties and returns true if at least one has a value.
/// ErrorMessage string must be specified!
///

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public sealed class MustHaveAtLeastOneOf : ValidationAttribute
{
private readonly object _typeId = new object();

public MustHaveAtLeastOneOf(params string[] properties)
: base("") {
MustHaveAtLeastOneOfProperties = properties;
}

public string[] MustHaveAtLeastOneOfProperties { get; private set; }

public override object TypeId {
get {
return _typeId;
}
}

public override string FormatErrorMessage(string name) {
return ErrorMessageString;
}

public override bool IsValid(object value) {
if (ErrorMessageString == null) { throw new ArgumentNullException("ErrorMessage string must be filled in when declaring the attribute."); }
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
//object originalValue = properties.Find(OriginalProperty, true /* ignoreCase */).GetValue(value);
//object confirmValue = properties.Find(ConfirmProperty, true /* ignoreCase */).GetValue(value);
//return Object.Equals(originalValue, confirmValue);
bool foundWithValue = false;
foreach (PropertyDescriptor prop in properties) {
if (MustHaveAtLeastOneOfProperties.Contains(prop.Name)) {
object val = prop.GetValue(value);
if (val != null && val.GetType().Name.ToLower().EndsWith("string")) {
if (string.IsNullOrWhiteSpace((string)val)) {
val = null;
}
}
if (val != null) {
foundWithValue = true;
}
}
}
return foundWithValue;
}
}

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 )

Connecting to %s