Opposite of [compare(" ")] data annotation in .net? Opposite of [compare(" ")] data annotation in .net? asp.net asp.net

Opposite of [compare(" ")] data annotation in .net?


This is the implementation (server side) of the link that @Sverker84 referred to.

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]public class UnlikeAttribute : ValidationAttribute{    private const string DefaultErrorMessage = "The value of {0} cannot be the same as the value of the {1}.";    public string OtherProperty { get; private set; }    public UnlikeAttribute(string otherProperty)        : base(DefaultErrorMessage)    {        if (string.IsNullOrEmpty(otherProperty))        {            throw new ArgumentNullException("otherProperty");        }        OtherProperty = otherProperty;    }    public override string FormatErrorMessage(string name)    {        return string.Format(ErrorMessageString, name, OtherProperty);    }    protected override ValidationResult IsValid(object value,        ValidationContext validationContext)    {        if (value != null)        {            var otherProperty = validationContext.ObjectInstance.GetType()                .GetProperty(OtherProperty);            var otherPropertyValue = otherProperty                .GetValue(validationContext.ObjectInstance, null);            if (value.Equals(otherPropertyValue))            {                return new ValidationResult(                    FormatErrorMessage(validationContext.DisplayName));            }        }        return ValidationResult.Success;    }}

Usage:

public string UserName { get; set; }[Unlike("UserName")]public string AlternateId { get; set; } 

Details about this implementation, and how to implement it client-side can be found here:

http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-2

http://www.macaalay.com/2014/02/25/unobtrusive-client-and-server-side-not-equal-to-validation-in-mvc-using-custom-data-annotations/


You can use the [NotEqualTo] data annotation operator included in MVC Foolproof Validation. I used it right now and it works great!

MVC Foolproof is an open source library created by @nick-riggs and has a lot of available validators. Besides doing server side validation it also does client side unobtrusive validation.

Full list of built in validators you get out of the box:

Included Operator Validators

[Is][EqualTo][NotEqualTo][GreaterThan][LessThan][GreaterThanOrEqualTo][LessThanOrEqualTo]

Included Required Validators

[RequiredIf][RequiredIfNot][RequiredIfTrue][RequiredIfFalse][RequiredIfEmpty][RequiredIfNotEmpty][RequiredIfRegExMatch][RequiredIfNotRegExMatch]

Note: if you plan to use MVC Foolproof lib and support Localization, make sure you apply the patch I provided here: https://foolproof.codeplex.com/SourceControl/list/patches


The complete code for both server side and client side validation is as follows:

[AttributeUsage(AttributeTargets.Property)]public class UnlikeAttribute : ValidationAttribute, IClientModelValidator{    private string DependentProperty { get; }    public UnlikeAttribute(string dependentProperty)    {        if (string.IsNullOrEmpty(dependentProperty))        {            throw new ArgumentNullException(nameof(dependentProperty));        }        DependentProperty = dependentProperty;    }    protected override ValidationResult IsValid(object value,        ValidationContext validationContext)    {        if (value != null)        {            var otherProperty = validationContext.ObjectInstance.GetType().GetProperty(DependentProperty);            var otherPropertyValue = otherProperty.GetValue(validationContext.ObjectInstance, null);            if (value.Equals(otherPropertyValue))            {                return new ValidationResult(ErrorMessage);            }        }        return ValidationResult.Success;    }    public void AddValidation(ClientModelValidationContext context)    {        MergeAttribute(context.Attributes, "data-val", "true");        MergeAttribute(context.Attributes, "data-val-unlike", ErrorMessage);        // Added the following code to account for the scenario where the object is deeper in the model's object hierarchy        var idAttribute = context.Attributes["id"];        var lastIndex = idAttribute.LastIndexOf('_');        var prefix = lastIndex > 0 ? idAttribute.Substring(0, lastIndex + 1) : string.Empty;        MergeAttribute(context.Attributes, "data-val-unlike-property", $"{prefix}{DependentProperty}");    }    private void MergeAttribute(IDictionary<string, string> attributes,        string key,        string value)    {        if (attributes.ContainsKey(key))        {            return;        }        attributes.Add(key, value);    }}

Then include the following in JavaScript:

$.validator.addMethod('unlike',function (value, element, params) {    var propertyValue = $(params[0]).val();    var dependentPropertyValue = $(params[1]).val();    return propertyValue !== dependentPropertyValue;});$.validator.unobtrusive.adapters.add('unlike',['property'],function (options) {    var element = $(options.form).find('#' + options.params['property'])[0];    options.rules['unlike'] = [element, options.element];    options.messages['unlike'] = options.message;});

Usage is as follows:

    public int FromId { get; set; }    [Unlike(nameof(FromId), ErrorMessage = "From ID and To ID cannot be the same")]    public int ToId { get; set; }