none
Appel d'une fonction du code behind au déchargement d'une page RRS feed

  • Question

  • Bonjour, 

     

    Je suis actuellement en train de créer un module de chat pour DotNetNuke.

    Je voudrais que lorsque l'utilisateur quitte la page (fermeture d'onglet ou changement de page) la fonction Leave() du code behind soit appellée. 

    Actuellement j'ajoute un évènement onbeforeunload qui clique sur un asp:Button avec une propriété OnClick="Leave".

    Cependant, cela ne semble pas fonctionner à tous les coups avec Chrome. En revanche avec Firefox, la méthode Leave() est bien appelée la plupart du temps. 

    L'évènement javascript est bien appelé, mais le click() ne lance pas Leave().

    <script type="text/javascript" language="javascript">
    
      window.onbeforeunload = function () {
    
        document.getElementById('<%= ButtonQuit.ClientID %>').click();
     
    
      };
    </script>
    
    <asp:Button ID="ButtonQuit" runat="server" OnClick="Leave" Text="Quit" />
    
    
    

    Est-ce la bonne méthode pour le faire? 

    Je reste à votre disposition si vous avez besoin du code complet. 

    mardi 8 mars 2011 08:37

Réponses

  • Bonjour,

    je pense que le __doPostBack n'a pas le temps de s'exécuter à la fermeture de la page.

    J'ai trouvé une solution (qui date de 2009, donc il faudra adapter) : http://forums.asp.net/p/1153888/1891072.aspx

    Je recopie ici la réponse intéressante :

    Here is a sample of calling a server-side method when a window is closed. The server-side functionality is written in C#, but is easily converted to VB by using http://authors.aspalliance.com/aldotnet/examples/translate.aspx

    It entails creating a separate page (in this sample, LogoffPage.aspx) to house the function (the page will never display), but multiple functions to call could be placed there and accessed via the QueryString. This is basically the same as creating a Web Service, which would be a better solution, but more difficult to post here.

    //////////////////////////////////////////////////////////////////////////
    // Page1.aspx
    //////////////////////////////////////////////////////////////////////////

    <script type="text/javascript">
    <!--
    function callAjax(webUrl, queryString)
    {
     var xmlHttpObject = null;
     try
     {
     // Firefox, Opera 8.0+, Safari...
     xmlHttpObject = new XMLHttpRequest();
     }
     catch(ex)
     {
     // Internet Explorer...
     try
     {
      xmlHttpObject = new ActiveXObject('Msxml2.XMLHTTP');
     }
     catch(ex)
     {
      xmlHttpObject = new ActiveXObject('Microsoft.XMLHTTP');
     }
     }
     if ( xmlHttpObject == null )
     {
     window.alert('AJAX is not available in this browser');
     return; 
     }
     xmlHttpObject.open("GET", webUrl + queryString, false); 
     xmlHttpObject.send();
     return xmlText;
    }
    // -->
    </script>
    <script type="text/javascript">
    <!--
    var g_isPostBack = false;
    window.onbeforeunload = function ()
    {
     if ( g_isPostBack == true )
     return;
     var closeMessage = 
     'You are exiting this page.\n' +
     'If you have made changes without saving, your changes will be lost.\n' +
     'Are you sure that you want to exit?';
     if ( window.event )
     {
     // IE only...
     window.event.returnValue = closeMessage;
     }
     else
     {
     // Other browsers...
     return closeMessage;
     }
     g_isPostBack = false;
    }
    window.onunload = function ()
    {
     if ( g_isPostBack == true )
     return;
     var webUrl = 'LogoffPage.aspx';
     var queryString = '?LogoffDatabase=Y&UserID=' + '<%= Session["UserID"] %>';
     var returnCode = callAjax(webUrl, queryString);
     //alert(returnCode);
    }
    // -->
    </script>
    

    //////////////////////////////////////////////////////////////////////////
    // Page1.aspx.cs
    //////////////////////////////////////////////////////////////////////////

    private void Page_Load(object sender, System.EventArgs e)
    {
     if ( this.IsPostBack )
     {
     this.Session["UserID"] = "12345";
     }
     this.RegisterOnSubmitStatement("OnSubmitScript", "g_isPostBack = true;");
    }
    
    //////////////////////////////////////////////////////////////////////////
    // LogoffPage.aspx.cs
    //////////////////////////////////////////////////////////////////////////
    protected string LogoffUser(string userId)
    {
     string returnValue = "OK";
     // Call the database, logging the user off here...
     return returnValue;
    }
    private void Page_Load(object sender, System.EventArgs e)
    {
     string logoffDatabase = (this.Request["LogoffDatabase"] == null) ? string.Empty : this.Request["LogoffDatabase"];
     string returnValue = string.Empty;
     if ( logoffDatabase == "Y" )
     {
     if ( returnValue.Length > 0 )
      returnValue += ", ";
     returnValue += this.LogoffUser(this.Session["UserID"].ToString());
     }
     this.Response.ClearHeaders();      
     this.Response.Clear();
     this.Response.Write(returnValue);
     this.Response.End();
    }
    

    NC...

    En gros, pour expliquer ce qu'il fait :
    A la fermeture de Page1.aspx, il lance une requête Ajax vers LogoffPage.aspx... cette requête étant asynchrone elle n'est pas interrompu par la fermeture du navigateur.


    Sebastien FERRAND MVP C# (2004-2009) http://www.sfphotographie.fr
    • Proposé comme réponse Alex Petrescu jeudi 10 mars 2011 12:24
    • Marqué comme réponse Yohan D jeudi 10 mars 2011 12:32
    mercredi 9 mars 2011 08:53

Toutes les réponses

  • Bonjour,

    Pour des raisons de sécurités, il n'est normalement plus possible de "cliquer" automatiquement sur un bouton.

    Cependant vu que vous utilisez ASP.net pourquoi ne pas faire un __doPostBack sur votre bouton ?

    <script type="text/javascript" language="javascript">
    
     window.onbeforeunload = function () {
       __doPostBack('<%= ButtonQuit.ClientID %>','');
     };
    </script>
    

    Sebastien FERRAND MVP C# (2004-2009) http://www.sfphotographie.fr
    mardi 8 mars 2011 09:39
  • J'ai essayé en mettant le __doPostBack() mais sans succès.

    J'ai mis un point d'arrêt dans la méthode Leave() mais il n'est jamais atteint avec aucun des navigateurs. J'ai réésayé avec en mettant mon ancienne méthode (avec le click() et cela ne fonctionne plus non plus)

     

    En revanche j'arrive bien à afficher un alert() que ce soit avant ou après le __doPostBack. 

     

    Je mets le code complet ça pourra peut-être aider. 

     

     

    <script type="text/javascript" language="javascript">
    
     window.onbeforeunload = function () {
    
     //document.getElementById('<%= ButtonQuit.ClientID %>').click();
     __doPostBack('<%= ButtonQuit.ClientID %>', '');
     //alert("unload2");
    
     };
    
     function send() {
     document.getElementById('<%= ButtonSend.ClientID %>').click();
     document.getElementById('<%= TextBoxType2.ClientID %>').value = '';
     }
    
    </script>

    <asp:Timer ID="Timer1" runat="server" OnTick="Timer1_Tick" Interval="2000" />
    <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
    <Triggers>
     <asp:AsyncPostBackTrigger ControlID="Timer1" />
     </Triggers>
     <ContentTemplate>
     <asp:Label ID="Label1" runat="server">User Name:</asp:Label>
     <asp:TextBox ID="TextBoxName" runat="server" Height="37px" Width="381px"></asp:TextBox><br />
     <asp:Label ID="LabelError" runat="server" AutoUpdateAfterCallBack="True" UpdateAfterCallBack="True" /><br />
     <asp:ListBox ID="ListBoxMessages" runat="server" Height="352px" Width="80%" AutoUpdateAfterCallBack="True" CssClass="selectMessage" />
     <asp:ListBox ID="ListBoxNames" runat="server" Height="352px" Width="15%" AutoUpdateAfterCallBack="True" TextDuringCallBack="Loading..." />
     <input type="button" value="Send" style="width:90px;height:41px" onclick="send();" />
     <asp:Button ID="ButtonSend" runat="server" Height="41px" OnClick="ButtonSend_Click" Text="Send" Width="90px" style="display:none" />
     </ContentTemplate>
    </asp:UpdatePanel>
    <asp:TextBox ID="TextBoxType2" runat="server" Height="37px" Width="70%" MaxLength="77" CssClass="inputSend" />
    <asp:Button ID="ButtonQuit" runat="server" OnClick="Leave" Text="Quit" />


    mardi 8 mars 2011 16:17
  • Bonjour,

    je pense que le __doPostBack n'a pas le temps de s'exécuter à la fermeture de la page.

    J'ai trouvé une solution (qui date de 2009, donc il faudra adapter) : http://forums.asp.net/p/1153888/1891072.aspx

    Je recopie ici la réponse intéressante :

    Here is a sample of calling a server-side method when a window is closed. The server-side functionality is written in C#, but is easily converted to VB by using http://authors.aspalliance.com/aldotnet/examples/translate.aspx

    It entails creating a separate page (in this sample, LogoffPage.aspx) to house the function (the page will never display), but multiple functions to call could be placed there and accessed via the QueryString. This is basically the same as creating a Web Service, which would be a better solution, but more difficult to post here.

    //////////////////////////////////////////////////////////////////////////
    // Page1.aspx
    //////////////////////////////////////////////////////////////////////////

    <script type="text/javascript">
    <!--
    function callAjax(webUrl, queryString)
    {
     var xmlHttpObject = null;
     try
     {
     // Firefox, Opera 8.0+, Safari...
     xmlHttpObject = new XMLHttpRequest();
     }
     catch(ex)
     {
     // Internet Explorer...
     try
     {
      xmlHttpObject = new ActiveXObject('Msxml2.XMLHTTP');
     }
     catch(ex)
     {
      xmlHttpObject = new ActiveXObject('Microsoft.XMLHTTP');
     }
     }
     if ( xmlHttpObject == null )
     {
     window.alert('AJAX is not available in this browser');
     return; 
     }
     xmlHttpObject.open("GET", webUrl + queryString, false); 
     xmlHttpObject.send();
     return xmlText;
    }
    // -->
    </script>
    <script type="text/javascript">
    <!--
    var g_isPostBack = false;
    window.onbeforeunload = function ()
    {
     if ( g_isPostBack == true )
     return;
     var closeMessage = 
     'You are exiting this page.\n' +
     'If you have made changes without saving, your changes will be lost.\n' +
     'Are you sure that you want to exit?';
     if ( window.event )
     {
     // IE only...
     window.event.returnValue = closeMessage;
     }
     else
     {
     // Other browsers...
     return closeMessage;
     }
     g_isPostBack = false;
    }
    window.onunload = function ()
    {
     if ( g_isPostBack == true )
     return;
     var webUrl = 'LogoffPage.aspx';
     var queryString = '?LogoffDatabase=Y&UserID=' + '<%= Session["UserID"] %>';
     var returnCode = callAjax(webUrl, queryString);
     //alert(returnCode);
    }
    // -->
    </script>
    

    //////////////////////////////////////////////////////////////////////////
    // Page1.aspx.cs
    //////////////////////////////////////////////////////////////////////////

    private void Page_Load(object sender, System.EventArgs e)
    {
     if ( this.IsPostBack )
     {
     this.Session["UserID"] = "12345";
     }
     this.RegisterOnSubmitStatement("OnSubmitScript", "g_isPostBack = true;");
    }
    
    //////////////////////////////////////////////////////////////////////////
    // LogoffPage.aspx.cs
    //////////////////////////////////////////////////////////////////////////
    protected string LogoffUser(string userId)
    {
     string returnValue = "OK";
     // Call the database, logging the user off here...
     return returnValue;
    }
    private void Page_Load(object sender, System.EventArgs e)
    {
     string logoffDatabase = (this.Request["LogoffDatabase"] == null) ? string.Empty : this.Request["LogoffDatabase"];
     string returnValue = string.Empty;
     if ( logoffDatabase == "Y" )
     {
     if ( returnValue.Length > 0 )
      returnValue += ", ";
     returnValue += this.LogoffUser(this.Session["UserID"].ToString());
     }
     this.Response.ClearHeaders();      
     this.Response.Clear();
     this.Response.Write(returnValue);
     this.Response.End();
    }
    

    NC...

    En gros, pour expliquer ce qu'il fait :
    A la fermeture de Page1.aspx, il lance une requête Ajax vers LogoffPage.aspx... cette requête étant asynchrone elle n'est pas interrompu par la fermeture du navigateur.


    Sebastien FERRAND MVP C# (2004-2009) http://www.sfphotographie.fr
    • Proposé comme réponse Alex Petrescu jeudi 10 mars 2011 12:24
    • Marqué comme réponse Yohan D jeudi 10 mars 2011 12:32
    mercredi 9 mars 2011 08:53
  • Je n'ai pas essayer complètement cette solution, j'avais des petits soucis pour appeler la page logoff en javascript ( A cause de DotNetNuke je pense)

    J'ai fait des tests et il semblerait bien que comme vous l'avez dit le __doPostBack() n'a pas le temps de s'executer.

     

    J'ai finalement changé de méthode pour la connexion de l'utilisateur. J'utilise un TimeOut qui déconnecte supprime l'utilisateur de la liste si le serveur ne reçoit pas de PostBack au bout de 10secondes. 

     

    Dans tous les cas je vous remercie pour vos réponses. 

    jeudi 10 mars 2011 12:31