Webservices + ajax = une bonne méthode pour banir l'autopostback et augmenter la performance de vos pages

5/5 (8 avis)

Snippet vu 7 859 fois - Téléchargée 17 fois

Contenu du snippet

Une expérience que j'aimerais partager avec vous c'est celle de devoir supprimer un AutoPostBack sur une première DropDownList (DDL) qui fesait en sorte de remplir une autre DropDownList selon le choix de la première (il existe un lien 1 -> 0-N : c'est à dire que le faite de sélectionner une option dans le premier DDL généré 0 ou N options sur le 2eme DDL)

Source / Exemple :

/// <summary>
/// Description du WebService qui va récupérer les options du 2eme DDL
/// PS: lors de la création du webService via Visual Studio, ajouté à la main le ///[System.Web.Script.Services.ScriptService]
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class GetDDL2Options : System.Web.Services.WebService {

    public GetDDL2Options () {

        //Supprimez les marques de commentaire dans la ligne suivante si vous utilisez des composants conçus 
        //InitializeComponent(); 
    }

    [WebMethod]
    public string[] GetListOptionsDDL2(int iIDOptionDDL1)
    {             
        //PS : le DDL1 contient des objetcs que je nommerais oDDL1Object
        // de même le DDL 2 : oDDL2Object
        oDDL1Object o_DDL1 = new oDDL1Object();
        List<string> items = new List<string>();
        o_DDL1.ID = iIDOptionDDL1;
        //DDL2DB : classe de app_Code, qui interfere avec la Data Base afin de 
        // récupérer les objects en base de la DDL2 correspondant à un object
        // de la DDL1 (il existe une clé étrangère)
        ArrayList o_DDL2ObjectList = DDL2DB.GetDDL2ObjectsListForDDL2Object(o_DDL1);
        foreach (oDDL2Object oddl2 in o_DDL2ObjectList)
        {
            items.Add(oddl2.ID.ToString());
        }

        return items.ToArray();
    }
    
}

//Sur la page aspx il faut absolument insérer le ScriptManager de la façon suivante :

<asp:ScriptManager ID="ScriptManager1" runat="server">
        <Services>
            <!-- remplacez par le chemin de votre WebService -->
            <asp:ServiceReference Path="~local/GetDDL2Options.asmx" />
        </Services>
    </asp:ScriptManager> 

//à insérer dans la page concerné : 
<script type="text/javascript" language="javascript">
function GetDDL2ObjectsServiceJS()
       {
        var webServicePath='~local/GetDDL2Options.asmx';
        var webMethod='GetListOptionsDDL2';
        var iId1 = $get('<%=ddl_1.ClientID %>').selectedIndex;
        Sys.Net.WebServiceProxy.invoke(webServicePath, 
            webMethod, false,{"iIDOptionDDL1" : iId1}, OnSucceeded, 
            OnFailed,"User Context",1000000);

        }

        function OnSucceeded(result, eventArgs)
        {   
            // on ajoute                                                         
            AddItem('<%=ddl_2.ClientID%>',result,result);                                    
        }

        // le web service echoue.
        function OnFailed(error)
        {
            // affiche l'erreur.
            //lbl2 erreur permet juste de visualiser l'erreur    
            var RsltElem = document.getElementById("lbl2Error");
            RsltElem.innerHTML = "WebService Error: " + error.get_message();
        }
       
       //KD 22/04/2009 - Permet d'ajouter un element un une dropdownlist existante 
       function AddItem(DDL,Text,Value)
        {   
            var lg = 0;                                                               
            lg = document.getElementById(DDL).length;                                                                  
            var i=0;            
            var reg = new RegExp("[,;]+", "g");
            var tableauDDL2 = Text.toString().split(reg); 
            
            //On remet a zero la taille du select puis on ajoute une option vide
            document.getElementById(DDL).length = 0;
            var opt = document.createElement("option");                                                                                                        
                    document.getElementById(DDL).options.add(opt);
                    opt.text = "";
                    opt.value = "";
            
            
                                                                                                                                             
            for (var j=0; j<tableauDDL2.length; j++) {
                    var opt = document.createElement("option");                                                                                                        
                    document.getElementById(DDL).options.add(opt);
                    opt.text = tableauDDL2[j];
                    opt.value = tableauDDL2[j];                    
                                                        }                                                                                     
        }
        
        //Fonction récupérant la valeur de l'option du DDL2 sélectionné
        function RecupIDDDL2() {
           var iId2 = document.getElementById("ddl_2").value;
           //un champ caché permet de récupérer la valeur sélectionné 
           // dans le 2eme DDL pour le récupérer lors de la validation
           // du formulaire
           $('hf_idDDL2').value = iId2;
        }
</script>

//Dernière chose : entourer votre première DDL par un TD et sur son onClick appelé la //fonction  JS :
<td onclick="GetDDL2ObjectsServiceJS();">DDL1 *
                            <asp:DropDownList ID="ddl_1" runat="server">
                            </asp:DropDownList>                            
                                                                                                                                            
</td>

//Le ddl_2, le lbl2Error et le champ caché :
//PS : le DropDownList est au faite un select (c'est plus adapté qu'un composant .NET)
<td>DDL2 *
      <select id="ddl_Sillons" name="ddl_2" runat="server" onclick="RecupIDDDL2()">
      </select>                                    
      <input type="hidden" name="hf_idDDL2" id="hf_idDDL2" runat="server" />
      <asp:Label ID="lbl2Error" runat="server"></asp:Label>     
</td>

Conclusion :

Le contenu du code n'est pas une partie de plaisir mais il reste indispensable pour les alliés de la performance.

A voir également

Ajouter un commentaire Commentaires
billou_13 Messages postés 860 Date d'inscription jeudi 4 mars 2004 Statut Membre Dernière intervention 19 août 2014 29
23 avril 2009 à 13:54
Merci !
Source très intéressante d'utilisation de Web Services en javascript. A user et abuser dans les développements asp.net ^^

Pour information, un tel type de besoin peut aussi conclure à une implémentation via la mise en place d'un service "AJAX-enabled WCF Services" (Framework 3.5). La technique est quasi identique.
Un très bon tutorial: http://www.pluralsight.com/community/blogs/fritz/archive/2008/01/31/50121.aspx
cs_driver Messages postés 7 Date d'inscription jeudi 3 avril 2003 Statut Membre Dernière intervention 7 janvier 2011 55
23 avril 2009 à 14:43
De rien, c'est un très grand soulagement pour moi de pouvoir partager ce source avec la communauté Microsoft parce que j'ai passé beaucoup d'heures avant de pouvoir arriver à concevoir cette solution. Maintenant je sais que d'autres personne vont attrapé le HAPPY-CODING en découvrant rapidement cette solution.

Et merci pour le source en 3.5. Il me seras utile quand j'aurai à bosser sur ce framework. En ce moment je travaille sur la performance d'un site ASP.NET 2.0
cs_ClaudePelletier Messages postés 3 Date d'inscription vendredi 10 juillet 2009 Statut Membre Dernière intervention 4 août 2009
10 juil. 2009 à 21:30
Le PostBack de la première liste déroulante s'effectue quand même. En fait, au lieu de laisser le PostBack être géré par .NET (plus sécuritaire, stable et fiable), tu as créé ta propre fonction JavaScript (GetDDL2ObjectsServiceJS) qui appelle ton service Web.

Bref, ce que tu gagnes en performance, tu le perds probablement 10 fois en sécurité, en stabilité et en fiabilité. Ce code ne résisterait pas à un audit en sécurité applicative (il est facilement injectable). C'est une belle démonstration, mais il serait téméraire d'utiliser ce petit «truc» (déjà passablement connu) dans le cadre du développement d'un site transactionnel par exemple.
cs_driver Messages postés 7 Date d'inscription jeudi 3 avril 2003 Statut Membre Dernière intervention 7 janvier 2011 55
14 juil. 2009 à 01:00
t'as pas tord Claude Pelletier,
mais chaque méthode dispose d'un périmètre d'utilisation, il faut juste bien définir les priorité de chaque application et les besoins de chaque client...chaque application devient unique et c'est pour ça qu'on dispose toujours de boulo dans notre domaine et heureusement d'ailleurs :)
lassaad83 Messages postés 148 Date d'inscription vendredi 28 avril 2006 Statut Membre Dernière intervention 1 décembre 2009
11 sept. 2009 à 11:18
UpdatePanel ça te dit quelque chose ?

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.