0

이 사용자 지정 유효성 검사를 사용하고 있습니다.사용자 지정 특성 클라이언트 쪽 유효성 검사 내 컬렉션

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을 편집해야 내 이해를 바탕으로하지 않기 때문에?

답변

1

글쎄, 나는 해킹을 조금하면서 더러운 방식으로 해결했다.

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