CompareAttribute for case insensitive comparison

I use CompareAttribute in MVC3 and its performance. But I want to use the case-insensitive Code class. Is there any way to get this working

Thanks at Advance

 [CompareAttribute("ClassCode", ErrorMessageResourceName = "ClassCode_DontMatch", ErrorMessageResourceType = typeof(Resources.Class))] public string ConfirmClassCode {get; set; } 
+4
source share
3 answers

You can write a custom attribute that will be case insensitive:

 public class CaseInsensitiveCompareAttribute : System.Web.Mvc.CompareAttribute { public CaseInsensitiveCompareAttribute(string otherProperty) : base(otherProperty) { } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var property = validationContext.ObjectType.GetProperty(this.OtherProperty); if (property == null) { return new ValidationResult(string.Format(CultureInfo.CurrentCulture, "Unknown property {0}", this.OtherProperty)); } var otherValue = property.GetValue(validationContext.ObjectInstance, null) as string; if (string.Equals(value as string, otherValue, StringComparison.OrdinalIgnoreCase)) { return null; } return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName)); } } 

and then decorate with the property of the view model as follows:

 [CaseInsensitiveCompare("ClassCode", ErrorMessageResourceName = "ClassCode_DontMatch", ErrorMessageResourceType = typeof(Resources.Class))] public string ConfirmClassCode { get; set; } 
+7
source

A bit late for the party, but here is the implementation I just wrote that also includes support for client-side validation using the IClientValidatable interface. You could also use Darin Dimitrov’s answer as a starting point, I already had some of this.

Server side validation:

 //Create your custom validation attribute [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)] public class CompareStrings : ValidationAttribute, IClientValidatable { private const string _defaultErrorMessage = "{0} must match {1}"; public string OtherPropertyName { get; set; } public bool IgnoreCase { get; set; } public CompareStrings(string otherPropertyName) : base(_defaultErrorMessage) { if (String.IsNullOrWhiteSpace(otherPropertyName)) throw new ArgumentNullException("OtherPropertyName must be set."); OtherPropertyName = otherPropertyName; } public override string FormatErrorMessage(string name) { return String.Format(ErrorMessage, name, OtherPropertyName); } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { string otherPropVal = validationContext.ObjectInstance.GetType().GetProperty(OtherPropertyName).GetValue(validationContext.ObjectInstance, null) as string; //Convert nulls to empty strings and trim spaces off the result string valString = (value as string ?? String.Empty).Trim(); string otherPropValString = (otherPropVal ?? String.Empty).Trim(); bool isMatch = String.Compare(valString, otherPropValString, IgnoreCase) == 0; if (isMatch) return ValidationResult.Success; else return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); } 

Client side validation

  //...continuation of CompareStrings class public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { return new[] { new ModelClientValidationCompareStringsRule(FormatErrorMessage(metadata.GetDisplayName()), OtherPropertyName, IgnoreCase) }; } } 

Define a ModelClientValidationCompareStringsRule that is used (above) to pass the attribute properties to the client-side script.

 public class ModelClientValidationCompareStringsRule : ModelClientValidationRule { public ModelClientValidationCompareStringsRule(string errorMessage, string otherProperty, bool ignoreCase) { ErrorMessage = errorMessage; //The error message to display when invalid. Note we used FormatErrorMessage above to ensure this matches the server-side result. ValidationType = "comparestrings"; //Choose a unique name for your validator on the client side. This doesn't map to anything on the server side. ValidationParameters.Add("otherprop", otherProperty); //Pass the name of the property to compare to ValidationParameters.Add("ignorecase", ignoreCase.ToString().ToLower()); //And whether to ignore casing } } 

Javascript:

 (function ($) { //Add an adapter for our validator. This maps the data from the ModelClientValidationCompareStringsRule //we defined above, to the validation plugin. Make sure to use the same name as we chose for the ValidationType property ("comparestrings") $.validator.unobtrusive.adapters.add("comparestrings", ["otherprop", "ignorecase"], function (options) { options.rules["comparestrings"] = { otherPropName: options.params.otherprop, ignoreCase: options.params.ignorecase == "true" }; options.messages["comparestrings"] = options.message; }); //Add the method, again using the "comparestrings" name, that actually performs the client-side validation to the page validator $.validator.addMethod("comparestrings", function (value, element, params) { //element is the element we are validating and value is its value //Get the MVC-generated prefix of element //(EG "MyViewModel_" from id="MyViewModel_CompareEmail" var modelPrefix = getModelIDPrefix($(element).prop("id")); //otherPropName is just the name of the property but we need to find //its associated element to get its value. So concatenate element's //modelPrefix with the other property name to get the full MVC-generated ID. If your elements use your own, overridden IDs, you'd have to make some modifications to allow this code to find them (eg finding by the name attribute) var $otherPropElem = $("#" + modelPrefix + params.otherPropName); var otherPropValue = getElemValue($otherPropElem); //Note: Logic for comparing strings needs to match what it does on the server side //Trim values value = $.trim(value); otherPropValue = $.trim(otherPropValue); //If ignoring case, lower both values if (params.ignoreCase) { value = value.toLowerCase(); otherPropValue = otherPropValue.toLowerCase(); } //compare the values var isMatch = value == otherPropValue; return isMatch; }); function getElemValue(element){ var value; var $elem = $(element); //Probably wouldn't use checkboxes or radio buttons with //comparestrings, but this method can be used for other validators too if($elem.is(":checkbox") || $elem.is(":radio") == "radio") value = $elem.prop("checked") ? "true" : "false"; else value = $elem.val(); return value; } //Gets the MVC-generated prefix for a field by returning the given string //up to and including the last underscore character function getModelIDPrefix(fieldID) { return fieldID.substr(0, fieldID.lastIndexOf("_") + 1); } }(jQuery)); 

Usage is standard:

 public string EmailAddress { get; set; } [CompareStrings("EmailAddress", ErrorMessage = "The email addresses do not match", IgnoreCase=true)] public string EmailAddressConfirm { get; set; } 

This connects to an unobtrusive verification infrastructure, so it should already be installed and working. At the time of this writing, I am on Microsoft.jQuery.Unobtrusive.Validation v 3.0.0.

+7
source

For client side verification, put this code below in the ready- document

 jQuery.validator.addMethod("ignoredCaseEqualTo", function (value, element, param) { return this.optional(element) || value.toLowerCase() === $(param).val().toLowerCase(); }, "__Your Validation message___"); $("#EmailAddress").rules("add", { ignoredCaseEqualTo: "#EmailAddressConfirm" }); 

this code adds a new case-insensitive validation rule. It may not be the best way, but it will do your job for client-side validation.

0
source

Source: https://habr.com/ru/post/1438939/


All Articles