Validation MVC inférieure/supérieure à l'autre valeur
Comment est la meilleure façon de valider un modèle MVC.Net où je veux accepter un minimum / maximum.
pas de valeurs min / max individuelles pour un champ. Mais des champs séparés pour un utilisateur de spécifier une durée minimale/maximale.
public class FinanceModel{
public int MinimumCost {get;set;}
public int MaximumCost {get;set;}
}
je dois donc m'assurer que le coût minimum est toujours inférieur au coût Maximum.
5 réponses
vous pouvez utiliser un attribut de validation personnalisé voici mon exemple avec dates. Mais vous pouvez l'utiliser avec ints trop.
tout d'Abord, voici le modèle :
public DateTime Beggining { get; set; }
[IsDateAfterAttribute("Beggining", true, ErrorMessageResourceType = typeof(LocalizationHelper), ErrorMessageResourceName = "PeriodErrorMessage")]
public DateTime End { get; set; }
Et voici l'attribut lui-même :
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;
}
Il y a un paquet NuGet appelé Infaillible, qui fournit ces annotations pour vous. Cela dit - écrire un attribut personnalisé est à la fois assez facile et bonne pratique.
L'utilisation de la preuve infaillible ressemblerait à:
public class FinanceModel{
public int MinimumCost {get;set;}
[GreaterThan("MinimumCost")]
public int MaximumCost {get;set;}
}
Pour la validation côté client à l'aide de la allowEqualDates et propertyTested paramètres (complément à Boranas réponse ci-dessus, mais trop long pour un commentaire:
// 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;
});
}
Plus d'informations: validation discrète,jquery de validation
en VB pour les entiers:
modèle
<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
pourquoi vous n'êtes pas utilisé validateur de portée. Syntaxe:
[Range(typeof(int), "0", "100", ErrorMessage = "{0} can only be between {1} and {2}")]
public int Percentage { get; set; }