Convalida MVC inferiore / superiore a un altro valore

Come è il modo migliore per convalidare un modello in MVC.Net dove voglio accettare un minimo / massimo.

Non singoli valori min / max per un campo. Ma campi separati per un utente per specificare un minimo / massimo.

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

Quindi devo assicurarmi che MinimumCost sia sempre inferiore al costo massimo.

È ansible utilizzare un attributo di convalida personalizzato qui è il mio esempio con le date. Ma puoi usarlo anche con int.

Innanzitutto, ecco il modello:

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

Ed ecco l’attributo stesso:

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

C’è un pacchetto NuGet chiamato Foolproof che fornisce queste annotazioni per te. Detto questo, la scrittura di un attributo personalizzato è alquanto semplice e buona pratica.

L’uso di Foolproof potrebbe essere:

 public class FinanceModel{ public int MinimumCost {get;set;} [GreaterThan("MinimumCost")] public int MaximumCost {get;set;} } 

Per la validazione lato client utilizzando i parametri allowEqualDates e propertyTested (complementare alla risposta Boranas sopra ma troppo lunga per il commento):

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

Ulteriori informazioni: convalida discreta , validazione jquery

In VB per numeri interi:

MODELLO

  Public Property PropertyNameNumberEnds As Nullable(Of Integer) 

CONVALIDA

 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 

Perché non sei usato Range Validator. Sintassi:

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