2013-09-02 70 views
23

Cách tốt nhất để xác thực mô hình trong MVC.Net nơi tôi muốn chấp nhận tối thiểu/tối đa.Xác thực MVC Thấp hơn/Cao hơn giá trị khác

Không phải giá trị tối thiểu/tối đa riêng lẻ cho một trường. Nhưng các trường riêng biệt để người dùng chỉ định tối thiểu/tối đa.

public class FinanceModel{ 
    public int MinimumCost {get;set;} 
    public int MaximumCost {get;set;} 
} 

Vì vậy, tôi cần đảm bảo rằng MinimumCost luôn nhỏ hơn Chi phí tối đa.

Trả lời

21

Bạn có thể sử dụng thuộc tính xác thực tùy chỉnh ở đây là ví dụ của tôi có ngày tháng. Nhưng bạn có thể sử dụng nó với ints quá.

Thứ nhất, đây là mô hình:

public DateTime Beggining { get; set; } 

    [IsDateAfterAttribute("Beggining", true, ErrorMessageResourceType = typeof(LocalizationHelper), ErrorMessageResourceName = "PeriodErrorMessage")] 
    public DateTime End { get; set; } 

Và đây là thuộc tính riêng của mình:

public sealed class IsDateAfterAttribute : ValidationAttribute, IClientValidatable 
{ 
    private readonly string testedPropertyName; 
    private readonly bool allowEqualDates; 

    public IsDateAfterAttribute(string testedPropertyName, bool allowEqualDates = false) 
    { 
     this.testedPropertyName = testedPropertyName; 
     this.allowEqualDates = allowEqualDates; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var propertyTestedInfo = validationContext.ObjectType.GetProperty(this.testedPropertyName); 
     if (propertyTestedInfo == null) 
     { 
      return new ValidationResult(string.Format("unknown property {0}", this.testedPropertyName)); 
     } 

     var propertyTestedValue = propertyTestedInfo.GetValue(validationContext.ObjectInstance, null); 

     if (value == null || !(value is DateTime)) 
     { 
      return ValidationResult.Success; 
     } 

     if (propertyTestedValue == null || !(propertyTestedValue is DateTime)) 
     { 
      return ValidationResult.Success; 
     } 

     // Compare values 
     if ((DateTime)value >= (DateTime)propertyTestedValue) 
     { 
      if (this.allowEqualDates && value == propertyTestedValue) 
      { 
       return ValidationResult.Success; 
      } 
      else if ((DateTime)value > (DateTime)propertyTestedValue) 
      { 
       return ValidationResult.Success; 
      } 
     } 

     return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     var rule = new ModelClientValidationRule 
     { 
      ErrorMessage = this.ErrorMessageString, 
      ValidationType = "isdateafter" 
     }; 
     rule.ValidationParameters["propertytested"] = this.testedPropertyName; 
     rule.ValidationParameters["allowequaldates"] = this.allowEqualDates; 
     yield return rule; 
    } 
+7

Bạn cần phải hoàn thành ví dụ này với xác nhận client-side: 'jQuery.validator.addMethod ('isdateafter', function (giá trị, yếu tố, params) { nếu (!/Không hợp lệ | NaN/.test (ngày mới (giá trị))) { trả về ngày (giá trị) mới> Ngày mới(); } lợi nhuận làNaN (giá trị) && isNaN ($ (params) .val()) || (parseFloat (giá trị)> parseFloat ($ (params) .val())); }, ''); jQuery.validator.unobtrusive.adapters.add ('isdateafter', {}, chức năng (tùy chọn) { options.rules ['isdateafter'] = true; options.messages ['isdateafter'] = options.message; }); ' – LoBo

+0

Dường như có lỗi do dòng' if (this.allowEqualDates && value == propertyTestedValue) '. Điều này làm việc: 'if (this.allowEqualDates && value.Equals (propertyTestedValue))' hoặc thậm chí 'if (this.allowEqualDates && (DateTime) value == (DateTime) propertyTestedValue)'. – publicgk

26

Có một gói NuGet gọi Foolproof cung cấp những chú thích cho bạn. Điều đó nói rằng - viết một thuộc tính tùy chỉnh là cả hai thực hành khá dễ dàng và tốt.

Sử dụng hoàn hảo sẽ như thế nào:

public class FinanceModel{ 
    public int MinimumCost {get;set;} 

    [GreaterThan("MinimumCost")] 
    public int MaximumCost {get;set;} 
} 
+1

Chấp nhận trình xác thực tùy chỉnh giống như một công cụ học tập. Cảm ơn bạn đã tham khảo Foolproof. Sẽ giữ nó tiện dụng chỉ trong trường hợp anyway. –

+0

Cách thức không được chấp nhận dường như không chấp nhận các thông báo lỗi tùy chỉnh. –

+2

Thông báo lỗi tùy chỉnh được chỉ định là [GreaterThan ("MinimumCost"), ErrorMessage = "Phải nhiều hơn Chi phí tối thiểu"] –

-7

Tại sao bạn không sử dụng Phạm vi Validator. Cú pháp:

[Range(typeof(int), "0", "100", ErrorMessage = "{0} can only be between {1} and {2}")] 
    public int Percentage { get; set; } 
+2

Nếu bạn nhìn vào câu hỏi ban đầu hoặc câu trả lời hiện có, bạn sẽ thấy tình huống tôi đang cố xác thực là nơi người dùng có thể chọn giới hạn trên/dưới. Không phải khi họ phải nhập giá trị giữa các giá trị cao/thấp hiện có. –

6

Đối với xác nhận phía khách hàng sử dụng các allowEqualDates và các thông số propertyTested (bổ sung để Boranas trả lời trên nhưng quá dài cho bình luận):

// definition for the isdateafter validation rule 
if ($.validator && $.validator.unobtrusive) { 
    $.validator.addMethod('isdateafter', function (value, element, params) { 
     value = Date.parse(value); 
     var otherDate = Date.parse($(params.compareTo).val()); 
     if (isNaN(value) || isNaN(otherDate)) 
      return true; 
     return value > otherDate || (value == otherDate && params.allowEqualDates); 
    }); 
    $.validator.unobtrusive.adapters.add('isdateafter', ['propertytested', 'allowequaldates'], function (options) { 
     options.rules['isdateafter'] = { 
      'allowEqualDates': options.params['allowequaldates'], 
      'compareTo': '#' + options.params['propertytested'] 
     }; 
     options.messages['isdateafter'] = options.message; 
    }); 
} 

Thông tin thêm: unobtrusive validation, jquery validation

1

Trong VB cho số nguyên:

MODEL

<UtilController.IsIntegerGreatherOrEqualThan("PropertyNameNumberBegins", "PeriodErrorMessage")> 
     Public Property PropertyNameNumberEnds As Nullable(Of Integer) 

Validation

Public Class IsIntegerGreatherOrEqualThan 
     Inherits ValidationAttribute 

     Private otherPropertyName As String 
     Private errorMessage As String 

     Public Sub New(ByVal otherPropertyName As String, ByVal errorMessage As String) 
      Me.otherPropertyName = otherPropertyName 
      Me.errorMessage = errorMessage 
     End Sub 

     Protected Overrides Function IsValid(thisPropertyValue As Object, validationContext As ValidationContext) As ValidationResult 

      Dim otherPropertyTestedInfo = validationContext.ObjectType.GetProperty(Me.otherPropertyName) 

      If (otherPropertyTestedInfo Is Nothing) Then 
       Return New ValidationResult(String.Format("unknown property {0}", Me.otherPropertyName)) 
      End If 

      Dim otherPropertyTestedValue = otherPropertyTestedInfo.GetValue(validationContext.ObjectInstance, Nothing) 

      If (thisPropertyValue Is Nothing) Then 
       Return ValidationResult.Success 
      End If 

      '' Compare values 
      If (CType(thisPropertyValue, Integer) >= CType(otherPropertyTestedValue, Integer)) Then 
       Return ValidationResult.Success 
      End If 

      '' Wrong 
      Return New ValidationResult(errorMessage) 
     End Function 
    End Class 
+0

Tôi đã xóa "FormatErrorMessage" khỏi mã vì nó đã thêm "'The Field' + {errorMessage} + 'không hợp lệ'". Tôi đã làm một kiểm tra ngày, vì vậy tôi đã thay thế Integer bằng Date. Làm việc tuyệt vời và tiết kiệm thời gian cho tôi. Cảm ơn bạn. – PHBeagle

+0

Vì vậy, errorMessage đã hiển thị thông báo sai ?, khi tôi sử dụng nó, tôi đã không chú ý đến nó. – Dani

+0

Không thực sự sai, chỉ cần thêm từ ngữ. Bằng cách sử dụng "Return new ValidationResult (errorMessage)" thì nó tốt. – PHBeagle