2013-09-02 17 views
23

MVC.Net'te bir modeli minimum/maksimum kabul etmek istediğim yerde doğrulamanın en iyi yolu nasıl olur.MVC Doğrulama Alt/Diğer değerlerden daha yüksek

Bir alan için münferit min/maks değerleri değil. Ancak bir kullanıcının minimum/maksimum belirlemesi için ayrı alanlar.

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

yüzden MinimumCost hep Maksimum maliyetten daha az olmasını sağlamak gerekir.

cevap

21

Özel bir doğrulama özniteliği kullanabilirsiniz. Burada tarihlerim var. Ama bunu da mürekkeplerle kullanabilirsiniz.

Öncelikle burada modelidir:

public DateTime Beggining { get; set; } 

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

Ve burada nitelik kendisidir:

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

istemci tarafı doğrulama ile bu örnek tamamlamak için gereken: 'jQuery.validator.addMethod ('isdateafter', fonksiyon (değer, eleman, parametreler) { if (!/Invalid | NaN/.test (yeni Tarih (değer))) { yeni döndürür Date (value)> new Date(); } return isNaN (değer) && isNaN ($ (params) .val()) || (parseFloat (value)> parseFloat ($ (params) .val())); }, ''); jQuery.validator.unobtrusive.adapters.add ('isdateafter', {}, fonksiyon (seçenekler) { options.rules [ 'isdateafter'] = true; options.messages [ 'isdateafter'] = options.message; }); ' – LoBo

+0

" if (this.allowEqualDates && value == propertyTestedValue) "satırı nedeniyle bir hata var gibi görünüyor. Bu çalışır: 'if (this.allowEqualDates && value.Equals (propertyTestedValue))' veya hatta bu 'if (this.allowEqualDates && (DateTime) değeri == (DateTime) propertyTestedValue)'. – publicgk

26

sizin için bu açıklamaları sağlar Foolproof adında bir Nuget paketi yok. Bu dedi ki - özel bir özellik yazmak hem oldukça kolay hem de iyi bir uygulamadır.

gibi Foolproof görünecektir kullanma: Menzil Validator neden kullanılmadı

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

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

Özel doğrulayıcıyı bir öğrenim aracı olarak kabul etti. Foolproof referansı için teşekkürler. Yine de herzaman elimde olacak. –

+0

Foolproof, özel hata iletilerini kabul ediyor gibi görünmüyor. –

+2

Özel hata iletileri şu şekilde belirtilir [GreaterThan ("MinimumCost"), ErrorMessage = "Minimum Maliyet'ten daha fazlası olmalı"] –

-7

. dizimi:

istemci tarafı doğrulama için
[Range(typeof(int), "0", "100", ErrorMessage = "{0} can only be between {1} and {2}")] 
    public int Percentage { get; set; } 
+2

Orijinal soruma veya mevcut cevaplara bakarsanız, doğrulamaya çalıştığım durumun bir kullanıcının üst/alt sınırları seçebileceği yer olduğunu görürsünüz. Mevcut yüksek/düşük değerler arasında bir değer girmeleri gerektiğinde değil. –

6

allowEqualDates ve propertyTested parametreleri kullanarak (Boranas için tamamlayıcı yukarıda ama çok uzun yorum için cevap):

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

fazla bilgi: unobtrusive validation, jquery validation

1

Tamsayılar için VB:

MODEL

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

DOĞRULAMA

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

"FormatErrorMessage" öğesini koddan "Alan" + {errorMessage} + 'geçersiz "olarak ekledim. Bir tarih kontrolü yapıyordum, bu yüzden Tamsayı ile Tarih değiştirdim. Harika çalıştı ve bana zaman kazandırdı. Teşekkür ederim. – PHBeagle

+0

Yani errorMessage yanlış mesaj mı gösteriyordu? Ben kullandım, buna dikkat etmedim. – Dani

+0

Gerçekten yanlış, sadece ekstra ifade. "Yeni ValidationResult (errorMessage)" i kullanarak, o zaman iyiydi. – PHBeagle