Reputation: 91
I regularly use the CompareAttribute data annotation in my models to validate that two fields are equal. For example, most of us use it to compare a password and a confirm password field.
It may seems trivial but I wonder how to use such annotation to compare that two fields are differents. For instance, I would like to verify that the password is different from the username.
For more complex validations, I know I have to use custom validators, but I was just wondering if there was something built-in for that.
Thank you.
Upvotes: 1
Views: 2342
Reputation: 15188
You have two choices here, create your own ValidationAttribute inheriting from CompareAttribute
or inheriting from ValidationAttribute
.
1) Custom ValidationAttribute inherit from CompareAttribute
public class NotEqualAttribute : CompareAttribute
{
public string BasePropertyName { get; private set; }
private const string DefaultErrorMessage = "'{0}' and '{1}' must not be the same.";
public MyCustomCompareAttribut(string otherProperty)
: base(otherProperty)
{
BasePropertyName = otherProperty;
}
public override string FormatErrorMessage(string name)
{
return string.Format(DefaultErrorMessage, name, BasePropertyName);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var result = base.IsValid(value, validationContext);
if (result == null)
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
return null;
}
}
2)Custom ValidationAttribute inherit from ValidationAttribute
public class NotEqualAttribute : ValidationAttribute
{
private const string DefaultErrorMessage = "'{0}' and '{1}' must not be the same.";
public string BasePropertyName { get; private set; }
public NotEqualAttribute(string basePropertyName)
: base(DefaultErrorMessage)
{
BasePropertyName = basePropertyName;
}
public override string FormatErrorMessage(string name)
{
return string.Format(DefaultErrorMessage, name, BasePropertyName);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var property = validationContext.ObjectType.GetProperty(BasePropertyName);
if (property == null)
{
return new ValidationResult(
string.Format(
CultureInfo.CurrentCulture, "{0} is invalid property", BasePropertyName
)
);
}
var otherValue = property.GetValue(validationContext.ObjectInstance, null);
if (object.Equals(value, otherValue))
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
return null;
}
}
Then you can use either one like:
public class YourModelClass
{
public string PropertyA{ get; set; }
[NotEqual("PropertyA")]
public string PropertyB{ get; set; }
}
Upvotes: 4