簡體   English   中英

CompareAttribute用於不區分大小寫的比較

[英]CompareAttribute for case insensitive comparison

我在MVC3使用CompareAttribute並且工作正常。 但我想使用不區分大小寫的classCode。 有沒有辦法讓它工作

提前致謝

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

您可以編寫一個自定義屬性來執行不區分大小寫的比較:

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

然后用它裝飾你的視圖模型屬性:

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

派對有點晚了,但這里是我剛剛編寫的一個實現,它還包括使用IClientValidatable接口支持客戶端驗證。 您也可以使用Darin Dimitrov的答案作為起點,我剛剛已經有了一些這樣的答案。

服務器端驗證:

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

客戶端驗證

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

定義ModelClientValidationCompareStringsRule,使用(上面)將屬性的屬性傳遞給客戶端腳本。

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's 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
        //(E.G. "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 (e.g. 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));

用法是標准的:

public string EmailAddress { get; set; }

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

這將插入Unobtrusive Validation框架,因此您需要已安裝並正常工作。 在撰寫本文時,我使用的是Microsoft.jQuery.Unobtrusive.Validation v 3.0.0。

對於客戶端驗證,請將此代碼放入文檔准備中 -

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

此代碼添加了不區分大小寫比較的新驗證規則。 可能不是最佳方式,但這將為客戶端驗證做好准備。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM