2013-09-02 13 views
23

Jak najlepiej sprawdzić poprawność modelu w MVC.Net, gdzie chcę zaakceptować minimum/maksimum.Walidacja MVC Dolna/Wyższa niż inna wartość

Nieszczególne wartości min/maks dla pola. Ale oddzielne pola dla użytkownika, aby określić minimum/maksimum.

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

Muszę więc zapewnić, że Minimalny koszt jest zawsze niższy niż Maksymalny koszt.

Odpowiedz

21

Możesz użyć niestandardowego atrybutu sprawdzania tutaj mój przykład z datami. Ale możesz go również używać z ints.

pierwsze, oto model:

public DateTime Beggining { get; set; } 

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

A oto sam atrybut:

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

Musisz zakończyć ten przykład z walidacji po stronie klienta: 'jQuery.validator.addMethod ('isdateafter', funkcji (wartość, element, params) { if (!/Invalid | NaN/.test (new Date (value))) { return new Date (value)> new Date(); } return isNaN (wartość) && isNaN ($ (parametry) .val()) || (parseFloat (wartość)> parseFloat ($ (params) .val())); }, ''); jQuery.validator.unobtrusive.adapters.add ('isdateafter', {}, funkcja (opcje) { options.rules ['isdateafter'] = true; options.messages ['isdateafter'] = options.message; }); ' – LoBo

+0

Wygląda na to, że istnieje błąd związany z linią' if (this.allowEqualDates && value == propertyTestedValue) '. Działa to: 'if (this.allowEqualDates && value.Equals (propertyTestedValue)) lub nawet tego' if (this.allowEqualDates && (DateTime) value == (DateTime) propertyTestedValue). – publicgk

26

Jest to pakiet Nuget nazywa Foolproof który zapewnia te adnotacje dla Ciebie. To powiedziawszy - napisanie niestandardowego atrybutu jest zarówno łatwe, jak i dobre.

Korzystanie Niezawodny wyglądałby następująco:

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

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

Zaakceptował niestandardowy weryfikator jako narzędzie do nauki. Dzięki za referencję do Foolproof. Czy to będzie przydatne, mimo wszystko podbić. –

+0

Foolproof nie akceptuje niestandardowych komunikatów o błędach. –

+2

Własne komunikaty o błędach są określone jako takie [GreaterThan ("MinimumCost"), ErrorMessage = "Musi być większy niż minimalny koszt"] –

-7

Dlaczego nie służą Zakres Validator. Składnia:

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

Jeśli spojrzysz na moje oryginalne pytanie lub istniejące odpowiedzi, zobaczysz, że sytuacja, którą próbuję sprawdzić, to miejsce, w którym użytkownik może wybrać górny/dolny limit. Nie wtedy, gdy muszą wprowadzić wartość między istniejącymi wartościami górnymi/dolnymi. –

6

walidacji po stronie klienta przy użyciu allowEqualDates i parametry propertyTested (uzupełnienie Boranas odpowiedzieć powyżej, ale zbyt długo komentarzu):

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

Więcej informacji: unobtrusive validation, jquery validation

1

W VB dla liczb całkowitych:

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

Usunąłem "FormatErrorMessage" z kodu podczas dodawania "" Pole "+ {errorMessage} +" jest nieprawidłowe "". Robiłem sprawdzanie daty, więc zastąpiłem Integer datą. Świetnie pracował i uratował mi czas. Dziękuję Ci. – PHBeagle

+0

Więc errorMessage wyświetlał nieprawidłowy komunikat ?, kiedy go użyłem, nie zwracałem na to uwagi. – Dani

+0

Nie bardzo źle, tylko dodatkowe sformułowania. Używając "Return new ValidationResult (errorMessage)", było dobrze. – PHBeagle

Powiązane problemy