MVC de validation personnalisée: comparer deux dates

J'ai créé une coutume ValidationAttribute qui compare les 2 dates et permet de s'assurer que la deuxième date est supérieure à la première:

public sealed class IsDateAfter : ValidationAttribute, IClientValidatable
{
private readonly string testedPropertyName;
private readonly bool allowEqualDates;
public IsDateAfter(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)
{
return ValidationResult.Success;
}
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;
}

CalendarEntry classe:
...

public virtual DateTime StartDate { get; set; }
[IsDateAfter("StartDate", true, ErrorMessage="End date needs to be after start date")]
public virtual DateTime EndDate { get; set; }

VUE:

$.validator.unobtrusive.adapters.add(
'isdateafter', ['propertytested', 'allowequaldates'], function (options) {
options.rules['isdateafter'] = options.params;
options.messages['isdateafter'] = options.message;
});
$.validator.addMethod("isdateafter", function(value, element, params) {
alert(params.propertytested);
var startdatevalue = $('input[name="' + params.propertytested + '"]').val();
if (!value || !startdatevalue) return true;
return (params.allowequaldates) ? Date.parse(startdatevalue) <= Date.parse(value) : Date.parse(startdatevalue) < Date.parse(value);
}, '');

Cela fonctionne très bien lorsque l' CalendarEntry n'est pas appliqué à l'intérieur d'une autre classe. CEPENDANT, lorsque j'utilise un modèle d'affichage comme suit:

    public class TrainingDateEditViewModel
{
#region Properties
///<summary>
///Gets or sets CalendarEntry.
///</summary>
public CalendarEntry CalendarEntry { get; set; }
....

La validation du client ne fonctionne plus à cause de la sortie html produite est: est-ce

<input type="text" value="" name="CalendarEntry.EndDate" id="CalendarEntry_EndDate" data-val-isdateafter-propertytested="StartDate" data-val-isdateafter-allowequaldates="True" data-val-isdateafter="End date needs to be after start date" data-val="true">

Et la

data-val-isdateafter-propertytested="StartDate" and IT SHOULD BE: "CalendarEntry.StartDate".

Comment pourrais-je faire pour qu'elle sait à lier à "CalendarEntry.StartDate"
la règle.ValidationParameters["propertytested"] = ce.testedPropertyName; //ICI, IL convient de NOM COMPLET??? COMMENT??

grâce

  • merci pour ce code, j'ai mis en œuvre avec succès dans ma validation
  • Merci à vous, pour cela, et @counsellorben pour la mise à jour.
  • Peut-être une bonne idée de le Suffixe de votre classe avec Attribute
InformationsquelleAutor ShaneKm | 2011-08-11