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

StackOverflow https://stackoverflow.com/questions/21685117

Domanda

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.

È stato utile?

Soluzione

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; }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top