16

내 모델의 값이 내 모델의 다른 두 값 범위 내에 있어야합니다. 예를 들어MVC 동적 값의 눈에 띄지 않는 범위 유효성 검사

: 그들은 상수 값으로 가지고 물론

public class RangeValidationSampleModel 
{ 
    int Value { get; set; } 

    int MinValue { get; set; } 

    int MaxValue { get; set; } 
} 

, 내가이 최소/MaxValues를 전달할 수 없습니다 내 DataAnnotations로, 속성.

나는 내 자신의 유효성 검사 속성을 만들어야한다고 확신하지만이 작업을 많이 수행하지는 않았으며 작동 방법에 대한 내 마음을 감쌀 수 없습니다.

약 1 시간 동안 검색 한 결과 사용자 지정 유효성 검사를 작성하는 데 필요한 모든 솔루션이 있지만 MVC3의 눈에 띄지 않는 유효성 검사를 사용하여이 특정 문제를 해결할 수있는 방법이 없습니다.

+0

클라이언트 측 유효성 검사가 필요합니까? –

+1

좋습니다. 우리는이 사이트를 MVC2에서 MVC3으로 변환하고 있습니다. 현재 MVC2 유효성 검사가 클라이언트 측에서 작동하고 있으므로이 방법을 계속 사용하고 싶습니다. 그러나 가능한 경우 눈에 거슬리지 않은 유효성 검사를 사용하고 싶습니다. 현재 유효성 검사는 매우 눈에 띄지 않습니다. :) –

답변

34

: 그것으로보기 모델을 장식 한 후

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 RangeValidationSampleModel 
{ 
    [DynamicRangeValidator("MinValue", "MaxValue", ErrorMessage = "Value must be between {0} and {1}")] 
    public int Value { get; set; } 
    public int MinValue { get; set; } 
    public int MaxValue { get; set; } 
} 

는 다음 뷰를 제공하는 컨트롤러를 할 수 :

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new RangeValidationSampleModel 
     { 
      Value = 5, 
      MinValue = 6, 
      MaxValue = 8 
     }); 
    } 

    [HttpPost] 
    public ActionResult Index(RangeValidationSampleModel model) 
    { 
     return View(model); 
    } 
} 

물론보기 :

@model RangeValidationSampleModel 

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script> 
<script type="text/javascript"> 
    $.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) { 
      var message = $(element).attr('data-val-dynamicrange'); 
      $.validator.messages.dynamicrange = $.validator.format(message, minValue, maxValue); 
      return false; 
     } 
     return true; 
    }, ''); 
</script> 

@using (Html.BeginForm()) 
{ 
    <div> 
     @Html.LabelFor(x => x.Value) 
     @Html.EditorFor(x => x.Value) 
     @Html.ValidationMessageFor(x => x.Value) 
    </div> 
    <div> 
     @Html.LabelFor(x => x.MinValue) 
     @Html.EditorFor(x => x.MinValue) 
    </div> 
    <div> 
     @Html.LabelFor(x => x.MaxValue) 
     @Html.EditorFor(x => x.MaxValue) 
    </div> 
    <button type="submit">OK</button> 
} 

분명히 사용자 정의 어댑터 등록은 뷰를 오염시키는 것을 피하기 위해 외부 자바 스크립트 파일에서 수행해야하지만이 포스트의 목적과 간결함을 위해 뷰 내부에 넣었습니다.

+1

대린 감사합니다, 이것은 대단합니다! 자바 스크립트 코드를 두 번 조금 수정해야했습니다. 'isNaN' 검사가 취소되었고 ('!'을 제거해야했습니다), 메시지가 올바르게 설정 될 수 있도록'isNaN' 검사를 사용하여 최소/최대 검사를 이동했습니다. –

+0

@ JeradRose, 실제로 제 코드에 실수가있었습니다. 나는 그것을 지금 고쳤다. 문제가있는 경우 내 답변도 업데이트하는 것을 주저해서는 안됩니다. –

+0

감사합니다. 나는 그것을 편집하는 것을 고려했다. 그러나 나는 아직 그것을 할 수있는 권한이 없다 (나는 2k라고 생각한다). –

2

사용자 지정 유효성 검사 속성은 실제로 좋은 생각입니다. 같은 (일부 조각의 o'mine을 파고 누가 어디에 얼마 전에 알고 있음) :

public sealed class MustBeGreaterThan : ValidationAttribute 
{ 
    private const string _defaultErrorMessage = "'{0}' must be greater than '{1}'"; 
    private string _basePropertyName; 

    public MustBeGreaterThan(string basePropertyName) 
     : base(_defaultErrorMessage) 
    { 
     _basePropertyName = basePropertyName; 
    } 

    //Override default FormatErrorMessage Method 
    public override string FormatErrorMessage(string name) 
    { 
     return string.Format(_defaultErrorMessage, name, _basePropertyName); 
    } 

    //Override IsValid 
    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var basePropertyInfo = validationContext.ObjectType.GetProperty(_basePropertyName); 
     var lowerBound = (int)basePropertyInfo.GetValue(validationContext.ObjectInstance, null); 
     var thisValue = (int)value; 

     if (thisValue < lowerBound) 
     { 
      var message = FormatErrorMessage(validationContext.DisplayName); 
      return new ValidationResult(message); 
     } 

     //value validated 
     return null; 
    } 
} 

public sealed class MustBeLowerThan : ValidationAttribute 
{ 
    private const string _defaultErrorMessage = "'{0}' must be lower than '{1}'"; 
    private string _basePropertyName; 

    public MustBeLowerThan(string basePropertyName) 
     : base(_defaultErrorMessage) 
    { 
     _basePropertyName = basePropertyName; 
    } 

    //Override default FormatErrorMessage Method 
    public override string FormatErrorMessage(string name) 
    { 
     return string.Format(_defaultErrorMessage, name, _basePropertyName); 
    } 

    //Override IsValid 
    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var basePropertyInfo = validationContext.ObjectType.GetProperty(_basePropertyName); 
     var upperBound = (int)basePropertyInfo.GetValue(validationContext.ObjectInstance, null); 
     var thisValue = (int)value; 

     if (thisValue > upperBound) 
     { 
      var message = FormatErrorMessage(validationContext.DisplayName); 
      return new ValidationResult(message); 
     } 

     //value validated 
     return null; 
    } 
} 

는 클래스

public class RangeValidationSampleModel 
{ 
    [MustBeGreaterThan("MinValue")] 
    [MustBeLowerThan("MaxValue")] 
    int Value { get; set; } 

    int MinValue { get; set; } 

    int MaxValue { get; set; } 
} 

을 장식 당신은

+0

감사합니다 @ 렉스. 이것은 클라이언트 측의 눈에 거슬리지 않은 검증과 함께 작동하지 않는 것처럼 보입니다. –

0

을 갈 수 있어야한다 당신이 만약 클라이언트 쪽 유효성 검사가 필요합니다. 이는 사용자 지정이어야합니다. 나는 최근에 여기에 좋은 게시물을보고 어쨌든 (대린 드미 트로프 캔트 그것을 찾을 수가?) -이 클라이언트 검증이 발생 할 수 있습니다 : http://blogs.msdn.com/b/simonince/archive/2011/02/04/conditional-validation-in-asp-net-mvc-3.aspx

서버 측 IValidateableObject를 통해 처리하거나 할 수 Dynamic Range Validation in ASP.NET MVC 2

등 등에 서버 측이지만 클라이언트 측이 키가되기를 원한다고 느낍니다.

당신은이 목적을 위해 사용자 정의 유효성 검사 속성을 쓸 수
관련 문제