Comment DataAnnotations fonctionne-t-il vraiment dans MVC?

C’est plus une question théorique.

J’examine actuellement la validation de MVC 3 à l’aide de ComponentModel.DataAnnotations et tout fonctionne automatiquement, en particulier du côté client.

Quelque part, quelque chose vérifie ces atsortingbuts et génère du javascript pour la validation (ou des atsortingbuts html5, si vous utilisez le mode non intrusif), et cela fonctionne.

Ma question est que ce qui génère le javascript côté client et comment puis-je y accéder et le modifier? Par exemple, je veux traiter les atsortingbuts dataannotation donnés un peu différemment, ou gérer des atsortingbuts personnalisés (j’ai constaté que je pouvais les déduire de ValidationAtsortingbute, mais je ne veux peut-être pas pour une raison quelconque).

Quelqu’un peut-il m’expliquer ce qui se passe réellement? (Ou des liens vers de bonnes explications seraient également utiles, car je n’ai trouvé que des tutoriels pour utiliser réellement dataannotations)

EDIT: également avec ValidationAtsortingbute, la validation côté client ne fonctionne pas automatiquement. Pourquoi?

    MVC3 dispose d’un nouveau mécanisme de validation jQuery qui lie les métadonnées des atsortingbuts de validation et de validation jQuery. Il s’agit du fichier jquery.validate.unobtrusive qui prend tous data- atsortingbuts de data- et les jquery.validate.unobtrusive , comme auparavant lorsque vous définissez le paramètre.

      

    Tout ce que vous avez à faire est de créer vos propres atsortingbuts de validation personnalisés . Pour cela, vous avez 2 options:

    • Créez un atsortingbut de validation personnalisé qui hérite de l’interface ValidationAtsortingbute et remplacez IsValid

    ou

    • Créez un modèle à IValidatebleObjectIValidatebleObject l’aide du modèle IValidatebleObject , il vous suffit de renvoyer la méthode Validate

    dans MVC3, vous avez maintenant une méthode que vous pouvez remplacer, qui a un object ValidationContext , où vous pouvez simplement obtenir toutes les références, propriétés et valeurs de tout autre object du formulaire.

    Créez votre propre fichier et ce fichier discret gérera le mappage de ce dont votre validateur personnalisé a besoin et fonctionnera avec le plugin jQuery Validation.

    Vous ne changez pas le javascript … c’est sooo 90’s et non pas la manière MVC!

    par exemple si vous voulez valider, disons 2 dates que la dernière ne peut pas être inférieure à la première (période par exemple)

     public class TimeCard { public DateTime StartDate { get; set; } [GreaterThanDateAtsortingbute("StartDate")] public DateTime EndDate { get; set; } } 

    créer une validation personnalisée

     public class GreaterThanDateAtsortingbute : ValidationAtsortingbute { public ssortingng GreaterThanDateAtsortingbute(ssortingng otherPropertyName) :base("{0} must be greater than {1}") { OtherPropertyName = otherPropertyName; } public override ssortingng FormatErrorMessage(ssortingng name) { return Ssortingng.Format(ErrorMessageSsortingng, name, OtherPropertyName); } public override ValidateionResult IsValid(object value, ValidationContext validationContext) { var otherPropertyInfo = validationContext.ObjectTYpe.GetProperty(OtherPropertyName); var otherDate = (DateTime)otherPropertyInfo.GetValue(validationContext.ObjectInstance, null); var thisDate = (DateTime)value; if( thisDate <= otherDate ) { var message = FormatErrorMessage(validationContext.DisplayName); return new ValidationResult(message); } return null; } } 

    si vous utilisez le modèle d' auto-validation , le code serait simplement

     public IEnumerable Validate(ValidationContext validationContext) { if( EndDate <= StartDate ) yield return new ValidationResult("EndDate must be grater than StartDate"); } 

    N'oubliez pas que la validation personnalisée est générique, c'est pourquoi une grande partie du code et le modèle à validation automatique ne fonctionnent que sur le modèle appliqué.

    J'espère que ça aide


    ajoutée

    Je n'ai pas expliqué la partie relative à la validation du client personnalisé, je suis libre de vous demander si vous avez besoin d'exemples, mais en gros:

    C'est plus facile dans MVC3 (si vous comprenez bien sûr jQuery.Validate), il vous suffit de:

    • Implémenter IClientValidateble
    • Implémenter une méthode de validation jQuery
    • Implémenter un adaptateur discret

    Pour créer ces 3 choses, prenons ce GreaterThanDateAtsortingbute en compte et créons la validation côté client personnalisée. Pour cela, nous devons coder ceci:

    append à la GreaterThanDateAtsortingbute

     public IEnumerable GetCLientValidationRules(ModelMetadata metadata, ControllerContext context) { var rule = new ModelCLientValidationRule(); rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()); rule.ValidationType = "greater"; // This is what the jQuery.Validation expects rule.ValidationParameters.Add("other", OtherPropertyName); // This is the 2nd parameter yield return rule; } 

    Ensuite, vous devez écrire le nouveau validateur jQuery et l' adaptateur de métadonnées qui liera jQuery.Validation avec votre code fournissant les atsortingbuts de data- corrects pour ce champ (si bien sûr, UnobtrusiveJavaScriptEnabled est à true)

    créez un nouveau fichier js et attachez-le à votre par exemple,

      

    et annexer la nouvelle validation

     jQuery.validator.addMethod("greater", function(value, element, param) { // we need to take value and compare with the value in 2nd parameter that is hold in param return Date.parse(value) > Date.parse($(param).val()); }); 

    et puis on écrit l'adaptateur

     jQuery.validator.unobtrusive.adapters.add("greater", ["other"], function(options) { // pass the 'other' property value to the jQuery Validator options.rules["greater"] = "#" + options.param.other; // when this rule fails, show message that comes from ErrorMessage options.messages["greater"] = options.message; });