IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ASP.NET MVC Discussion :

[ASP MVC] ValidationAttribute côté client


Sujet :

ASP.NET MVC

  1. #1
    Membre régulier
    Profil pro
    Développeur Web
    Inscrit en
    Décembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Aube (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2008
    Messages : 55
    Points : 83
    Points
    83
    Par défaut [ASP MVC] ValidationAttribute côté client
    Bonjour tout le monde,

    Je suis un grand débutant en Asp.Net MVC. Voici le contexte :

    J'ai un formulaire pour permettre à un nouvel utilisateur de s'enregistrer. Dans ce formulaire, j'ai un champs Login et un champs Email, qui doivent être uniques. Afin de pouvoir tester cela, j'ai codé une classe héritée de ValidationAttribute, et si la contrainte de validation fonctionne bien côté serveur (à la validation du formulaire), rien ne se passe côté client (la validation n'est pas active lorsque je saisis un email existant et que je clique sur un autre champs) !
    Voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public class UsersModel
        {
            [Required(ErrorMessage="Une adresse email valide est requise")]
            [RegularExpression("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",ErrorMessage="L'email saisi ne respecte pas le format requis")]
            [SingleUser("Email", ErrorMessage="Un compte existe déjà avec cet email. Merci d'en saisir un nouveau")]
            public string Email { get; set; }
        }
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
        public class SingleUser : ValidationAttribute
        {
            private string Field{get;set;}
            public SingleUser(string field)
            {
                Field = field;
            }
     
            public override bool IsValid(object value)
            {
                string procedureToExecute = String.Empty;
                if (string.IsNullOrEmpty((string)value))
                {
                    return false;
                }
                if (Field != "Email" && Field != "Login")
                {
                    return false;
                }
                switch (Field)
                {
                    case "Email":
                        procedureToExecute = "dbo.BA_Users_GetUserByEmail";
                        break;
                    case "Login":
                        procedureToExecute = "dbo.BA_Users_GetUserByLogin";
                        break;
                }
     
                using (SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["BankAccount"].ConnectionString))
                {
     
                    sqlConnection.Open();
     
                    SqlCommand createUser = new SqlCommand(procedureToExecute, sqlConnection);
                    createUser.CommandType = CommandType.StoredProcedure;
                    createUser.Parameters.AddWithValue("@Value", value.ToString());
                    int result = (int)createUser.ExecuteScalar();
                    if (result >= 1)
                    {
                        return false;
                    }
                    return true;
                }
            }
        }
    Quelqu'un saurait-il m'aiguiller vers un tutoriel traitant des ValidationAttribute côté client ? Car malgré mes recherches, je ne suis tombé que sur des réponses de forums (dont le plus pertinent selon moi ci-dessous) que je n'arrive pas à appliquer dans mon cas (certainement du à mon niveau).
    http://forums.asp.net/p/1559594/3873161.aspx

    Je n'ai pas souhaité encombrer mon poste avec le code de la vue ou du controller, les validations required et regularexpression fonctionnant parfaitement côté client.

    Comme je l'ai dit, je suis débutant, donc si quelque chose dans mon code sans rapport avec les validationAttribute vous donne envie de vomir, je suis friand de toute suggestion d'amélioration.


    En vous remerciant par avance pour votre réponse.

    Cordialement

  2. #2
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Points : 8 080
    Points
    8 080
    Par défaut
    Je vais ptet dire une connerie, ca fait longtemps que j'ai plus fait sérieusement de l'ASP.
    Il me semble qu'il y'a des validationattribute qui ne peuvent pas être vérifiés côté client. Autant pour une regex ou un non-vide ca se traduit bien côté client en JScript, autant une unicité ca implique une requête sur le serveur.

  3. #3
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2007
    Messages
    871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2007
    Messages : 871
    Points : 1 498
    Points
    1 498
    Par défaut
    Salut,

    Je plussoie, j'ai eut la même problématique en aspnet (sans mvc) et à l'époque la seule solution que j'ai trouvé était de faire un appel ajax retournant le test de validation.

    Après, comment mettre en place un système similaire tout en se basant sut des attributs de validations je n'ai aucunes pistes à te donner.

  4. #4
    Membre régulier
    Inscrit en
    Avril 2004
    Messages
    213
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 213
    Points : 111
    Points
    111
    Par défaut
    Je t'invite à regarder ce lien c'est assez bien foutu:
    http://www.asp.net/mvc/tutorials/mvc-music-store-part-6

  5. #5
    Membre régulier
    Profil pro
    Développeur Web
    Inscrit en
    Décembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Aube (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2008
    Messages : 55
    Points : 83
    Points
    83
    Par défaut
    Hello tout le monde,

    Après quelques nuits blanches (heureusement que les projets persos ne sont pas soumis aux deadlines lol), j'ai pu trouver comment procéder :

    antrax2013, ton lien est en effet bien foutu, mais il explique uniquement comment faire des validateurs côté clients quand ceux-ci sont "standards", et non pour des validationAttributes personnalisés

    mermich, si tu as toujours la même problématique, je t'invite à lire ce qui suit, car en effet l'appel Ajax est à configurer, mais l'on reste dans le cadre d'un validationAttribute (rien de plus à ajouter dans le model, le view ou le controller)

    PitMaverick78, j'aurais envie de citer Jacques Coeur, "À coeur vaillant, rien d'impossible).

    Donc, voici comment procéder :

    Le code suivant (la première classe contient uniquement la méthode pour le test, mais ne concerne en rien les validationAttribute), contient une classe ValidationAttribute, qui ne change pas de mon précédent post (si ce n'est une factorisation du test), et une nouvelle classe, héritée de DataAnnotationsModelValidator, qui va permettre de spécifier les équivalences avec le modèle client que nous allons développer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
     
        public class SingleUserModel
        {
            public string field { get; set; }
            public string value { get; set; }
            public bool response { get; set; }
     
            public SingleUserModel(string _field, string _value)
            {
                field = _field;
                value = _value;
                response = CheckSingleUser(field, value);
            }
     
            public static bool CheckSingleUser(string _field, string _value)
            {
                string procedureToExecute = String.Empty;
                if (string.IsNullOrEmpty(_value))
                {
                    return false;
                }
                if (_field != "Email" && _field != "Login")
                {
                    return false;
                }
                switch (_field)
                {
                    case "Email":
                        procedureToExecute = "dbo.BA_Users_GetUserByEmail";
                        break;
                    case "Login":
                        procedureToExecute = "dbo.BA_Users_GetUserByLogin";
                        break;
                }
     
                using (SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["BankAccount"].ConnectionString))
                {
     
                    sqlConnection.Open();
     
                    SqlCommand createUser = new SqlCommand(procedureToExecute, sqlConnection);
                    createUser.CommandType = CommandType.StoredProcedure;
                    createUser.Parameters.AddWithValue("@Value", _value);
                    int result = (int)createUser.ExecuteScalar();
                    if (result >= 1)
                    {
                        return false;
                    }
                    return true;
                }
            }
     
     
     
     
        }
        public class SingleUserAttribute : ValidationAttribute
        {
            public string Field { get; private set; }
            public SingleUserAttribute(string field)
            {
                Field = field;
            }
     
            public override bool IsValid(object value)
                {
                    return SingleUserModel.CheckSingleUser(Field, (string)value);
                }
     
        }
        public class SingleUserValidator : DataAnnotationsModelValidator<SingleUserAttribute>
        {
            string _field;
            string _message;
     
            public SingleUserValidator(ModelMetadata metadata, ControllerContext context
              , SingleUserAttribute attribute)
                : base(metadata, context, attribute)
            {
                _field = attribute.Field;
                _message = attribute.ErrorMessage;
            }
     
            public override IEnumerable<ModelClientValidationRule>
             GetClientValidationRules()
            {
                var rule = new ModelClientValidationRule
                {
                    ErrorMessage = _message,
                    ValidationType = "field"
                };
                rule.ValidationParameters.Add("name", _field);
     
                return new[] { rule };
            }
        }
    }
    Ensuite, j'ai ajouté la chaîne suivante dans mon Global.asax.cs dans le Application_Start() (à la fin de la méthde) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(SingleUserAttribute), typeof(SingleUserValidator));
    Pour la suite, j'ai créé un fichier XML, dont je vous passerai le code, qui me génère True ou False en fonction d'un field et value qu'on lui transmet en paramètre GET.

    Pour finir, la création d'un script js qui va effectuer la requête Ajax vers mon fichier XML, et retourner le résultat en fonction de la valeur

    Le tout ajouté dans un objet JQuery créé par MVC.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    var singleUserAjaxResponse = (function(field, value) {
        var returnValue;
     
        $.ajax({
            url: "/Validators/SingleUser/Index/" + field + "/" + value,
            type: 'get',
            dataType: 'xml',
            async: false,
            success: function(data) {
                returnValue = $(data).find('Response').find('value').text();
            }
        });
     
        return returnValue;
    });
     
    Sys.Mvc.ValidatorRegistry.validators["field"] = function(rule) {
        var field = rule.ValidationParameters["name"];
     
        return function(value, context) {
            var ajaxCheckResponse = singleUserAjaxResponse(field, value);
            if (ajaxCheckResponse == "False") {
                return rule.ErrorMessage;
            }
            return true;
        };
    };
    Et voilà, un simple appel à ce js nouvellement créé dans mon formulaire, et mon Validator est opérationnel côté client.

    Si j'ai été un peu évasif, c'est parce que moi aussi n'ai pas tout compris, gros débutant que je suis, et donc beaucoup de copier/coller et d'adaptation pour arriver à ce résultat.

    Prochaine étape : comprendre ce que j'ai fait ;-)

    Cordialement

  6. #6
    Membre régulier
    Inscrit en
    Avril 2004
    Messages
    213
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 213
    Points : 111
    Points
    111
    Par défaut
    Je tiens à apporter un rectificatif à ce post. Je ne juge pas la façon de procéder ni le code. Je veux juste souligner que cette validation n'est pas faite côté client mais sur le serveur car elle repose sur une requête HTTP lancée via AJAX donc exécutée par le serveur.

    En fait je dis cela parce que je cherche une méthode pour valider côté client donc avant l'envoi de la requête HTTP dans le cas de l'utilisation d'une vue partielle.

    Dans une vue classique la méthode je vous donne un autre lien où il est clairement expliqué comment faire pour faire une validation avancée: la validation d'adresse mail:
    http://weblogs.asp.net/scottgu/archi...alidation.aspx

    Dans ton cas herfrayg, tu as besoin de ta base de données donc tu es obligé de repasser par le serveur et donc ta méthode doit marcher.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 17/11/2010, 10h53
  2. Update Pannel et ASP MVC 2
    Par litig dans le forum ASP.NET MVC
    Réponses: 1
    Dernier message: 20/05/2010, 09h43
  3. [ASP MVC] Validation formulaire en 4 étapes
    Par zax-tfh dans le forum ASP.NET
    Réponses: 1
    Dernier message: 30/11/2009, 12h10
  4. Réponses: 0
    Dernier message: 27/10/2009, 00h46
  5. Utiliser un service web asp.net dans un client Delphi
    Par oclone dans le forum Débuter
    Réponses: 1
    Dernier message: 15/05/2009, 14h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo