Q:

ASP MVC Data Annotation - How to verify that two model properties are different using CompareAttribute

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. 

A:

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; }
}

