簡體   English   中英

集合內的自定義屬性客戶端驗證

[英]Custom Attribute client side Validation inside Collection

我正在使用此自定義驗證。

public class DynamicRangeValidator : ValidationAttribute, IClientValidatable
{
    private readonly string _minPropertyName;
    private readonly string _maxPropertyName;

    public DynamicRangeValidator(string minPropertyName, string maxPropertyName)
    {
        _minPropertyName = minPropertyName;
        _maxPropertyName = maxPropertyName;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var minProperty = validationContext.ObjectType.GetProperty(_minPropertyName);
        var maxProperty = validationContext.ObjectType.GetProperty(_maxPropertyName);
        if (minProperty == null)
        {
            return new ValidationResult(string.Format("Unknown property {0}", _minPropertyName));
        }
        if (maxProperty == null)
        {
            return new ValidationResult(string.Format("Unknown property {0}", _maxPropertyName));
        }

        int minValue = (int)minProperty.GetValue(validationContext.ObjectInstance, null);
        int maxValue = (int)maxProperty.GetValue(validationContext.ObjectInstance, null);
        int currentValue = (int)value;
        if (currentValue <= minValue || currentValue >= maxValue)
        {
            return new ValidationResult(
                string.Format(
                    ErrorMessage,
                    minValue,
                    maxValue
                )
            );
        }

        return null;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ValidationType = "dynamicrange",
            ErrorMessage = this.ErrorMessage,
        };
        rule.ValidationParameters["minvalueproperty"] = _minPropertyName;
        rule.ValidationParameters["maxvalueproperty"] = _maxPropertyName;
        yield return rule;
    }
}

我的模特:

public class ProductModel{    
    public int MinValue{ get; set; }
    public int MaxValue{ get; set; }
    [DynamicRangeValidator("MinValue", "MaxValue", ErrorMessage = "Error Message")]
    public int Quantity{ get; set; }
}

視圖

@model IEnumerable<ProductModel>
@using (Html.BeginForm(action, controller){
    @for (int i = 0; i < Model.Items.Count; i++){
         @Html.EditorFor(m => Model.Items[i].Quantity)
         @Html.ValidationMessageFor(m => Model.Items[i].Quantity)
         @Html.HiddenFor(m=>Model.Items[i].MinValue)
         @Html.HiddenFor(m=>Model.Items[i].MaxValue)
    }
<input type="submit">
}

JS:

$.validator.unobtrusive.adapters.add('dynamicrange', ['minvalueproperty', 'maxvalueproperty'],
        function (options) {
            options.rules['dynamicrange'] = options.params;
            if (options.message != null) {
                $.validator.messages.dynamicrange = options.message;
            }
        });

$.validator.addMethod('dynamicrange', function (value, element, params) {
    var minValue = parseInt($('input[name="' + params.minvalueproperty + '"]').val(), 10);
    var maxValue = parseInt($('input[name="' + params.maxvalueproperty + '"]').val(), 10);
    var currentValue = parseInt(value, 10);
    if (!isNaN(minValue) || !isNaN(maxValue) || !isNaN(currentValue) || minValue >= currentValue || currentValue >= maxValue) {
        $.validator.messages.dynamicrange = $.format($.validator.messages.dynamicrange, minValue, maxValue);
        return false;
    }
    return true;
}, '');

服務器端驗證很好。 客戶端不,因為我渲染的html是

<input class="text-box single-line input-validation-error" data-val="true"
data-val-dynamicrange="Error Message"
data-val-dynamicrange-maxvalueproperty="MaxValue"
data-val-dynamicrange-minvalueproperty="MinValue"
data-val-number="The field Quantita must be a number."
id="Items_4__Quantity" name="Items[4].Quantity"
type="number" value="0">

代替

<input class="text-box single-line input-validation-error" data-val="true"
data-val-dynamicrange="Error Message"
data-val-dynamicrange-maxvalueproperty="Items_4__.MaxValue"
data-val-dynamicrange-minvalueproperty="Items_4__.MinValue"
data-val-number="The field Quantita must be a number."
id="Items_4__Quantity" name="Items[4].Quantity"
type="number" value="0">

根據我的理解,我應該編輯GetClientValidationRules以添加前綴(集合名稱和索引),但是如何?

好吧,我已經使用小技巧以骯臟的方式解決了。

//dirty way
var rule = new ModelClientValidationRule
{
    ValidationType = "dynamicrange",
    ErrorMessage = this.ErrorMessage,
};
string Prefix = ((System.Web.Mvc.ViewContext)(context)).ViewData.TemplateInfo.HtmlFieldPrefix;
Prefix = Prefix.Replace(metadata.PropertyName, "");
System.Text.RegularExpressions.Regex Regex = new System.Text.RegularExpressions.Regex("[^a-zA-Z0-9 -]");
Prefix = Regex.Replace(Prefix, "_");
rule.ValidationParameters["minvalueproperty"] = Prefix + _minPropertyName;
rule.ValidationParameters["maxvalueproperty"] = Prefix + _maxPropertyName;
yield return rule;

暫無
暫無

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

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