54 votes

Validation côté client avec paramètres en ASP.NET MVC 3

Dans le prolongement de ce billet Effectuer une validation côté client pour l'attribut personnalisé

J'essaie de comprendre comment faire, en passant des paramètres supplémentaires au script côté client.

D'après ce que j'ai compris jusqu'à présent, pour mettre en œuvre une validation personnalisée avec MVC 3, les éléments suivants sont nécessaires

Créer un attribut de validation personnalisé

Basé sur ValidationAttribute et implémentant IClientValidatable. J'ai également vu quelques exemples dérivant de ModelValidator, qui semble mettre en œuvre la fonctionnalité de ValidationAttribute et IClientValidatable. C'est donc mon premier point de confusion quant aux différences ou si ModelValidator était utilisé dans MVC 2 mais est maintenant déprécié ou quoi ?

Une instance de ModelClientValidationRule doit être renvoyée par GetClientValidationRules() pour spécifier des détails tels que le message d'erreur, ValidationType (qui, d'après ce que j'ai compris, est le nom de la fonction Javascript qui effectuera la validation côté client) et tout paramètre personnalisé supplémentaire que l'attribut peut avoir et qui doit être transmis à la validation Javascript.

Je suppose que le moteur d'exécution (je ne suis pas sûr de savoir quelle partie de celui-ci) utilise ensuite la fonction ModelClientValidationRule pour générer l'attribut html dans les éléments de balises comme suit :

data-val="true"  (to indicate that the element requires validation)
data-val-[ValidationType]=[ErrorMessage]
data-val-[ValidationType].[ValidationParameters(n).Key]=[ValidationParameters(n).Value]

Implémenter la logique de validation côté client

Une fonction Javascript doit être créée et ajoutée à jQuery.validators avec jQuery.validators.addmethod() afin que JQuery en ait connaissance lorsqu'elle doit être exécutée. Quelque chose comme :

jQuery.validator.addMethod(
    'greaterThan', 
    function (value, element, params) {
        /.../
       return /* true or false   */ ; 
    },
    ''
); 

Ma question est de savoir si la signature 'function (value, element, params)' est standard pour les méthodes qui gèrent la validation et je suppose qu'elle sera appelée par une fonctionnalité jQuery au moment opportun, par exemple avant qu'un formulaire ne soit soumis, lorsqu'un élément perd sa luminosité ou lors d'événements keyUp. Je ne comprends pas comment vous pouvez contrôler cela, c'est-à-dire choisir l'événement approprié pour votre validation personnalisée.

Implémenter un adaptateur discret

Cela traduit les attributs discrets en quelque chose de pas très clair, mais je suppose que c'est une règle jQuery, mais je ne sais pas comment cela fonctionne. Quelque chose comme

jQuery.validator.unobtrusive.adapters.add(
    'futuredate', 
    { },
    function (options) {
        options.rules['greaterThan'] = true;
        options.messages['greaterThan'] = options.message;
    }
); 

Ma question porte sur la "fonction (options)". Est-ce la fonction qui sera appelée avant 'function (value, element, params)' et qui est responsable de l'extraction des balises discrètes dans une structure de données qui peut être comprise par jQuery.Validation. D'après l'exemple de code, il me semble que les options sont un objet qui contient à la fois les valeurs d'attribut de la balise (comme options.message) et les propriétés jQuery pertinentes auxquelles elles doivent correspondre (comme options.messages['ClientSideValidationFunctionName']). Dans ce cas, comment les paramètres personnalisés sont-ils récupérés et mis en correspondance ?

J'espère ne pas avoir ajouté de confusion supplémentaire.

67voto

Darin Dimitrov Points 528142

Vous pourriez utiliser le ValidationParameters pour ajouter des paramètres personnalisés à la règle :

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
    var rule = new ModelClientValidationRule
    {
        ErrorMessage = this.ErrorMessage,
        ValidationType = "futuredate",
    };
    rule.ValidationParameters.Add("param1", "value1");
    rule.ValidationParameters.Add("param2", "value2");
    yield return rule;
}

qui pourrait être utilisé dans l'adaptateur :

jQuery.validator.unobtrusive.adapters.add(
    'futuredate', 
    [ 'param1', 'param2' ],
    function (options) {
        var param1 = options.params.param1; // shall equal 'value1'
        var param2 = options.params.param2; // shall equal 'value2'
        // TODO: use those custom parameters to define the client rules
    }
);

UPDATE :

Comme demandé dans la section des commentaires, voici comment vous pouvez transmettre ces paramètres à la fonction de règle du validateur personnalisé :

jQuery.validator.unobtrusive.adapters.add(
    'futuredate', 
    [ 'param1', 'param2' ],
    function (options) {
        // simply pass the options.params here
        options.rules['greaterThan'] = options.params;
        options.messages['greaterThan'] = options.message;
    }
);

jQuery.validator.addMethod('greaterThan', function (value, element, params) {
    // params here will equal { param1: 'value1', param2: 'value2' }
    return ...
}, '');

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X