Share via


Call c# method inside "onbeforeunload" event JS

Question

Tuesday, February 18, 2014 6:24 AM

Hi guys.

I have a Default.aspx that I implemented the code below. Inside this event I need call a C# method to unlink the current client that close the browser.

<script language="javascript" type="text/javascript">
        window.onbeforeunload = function (event) {
        };
</script>

My method is on Default.aspx.cs and call "UnlinkOperator" like below. Is a static void method because dont need return a value.

[System.Web.Services.WebMethod]
        public static void UnlinkOperator()
        {
            // O evento Session_End é disparado quando uma sessão do usuário finalizada ou é expirada.
            Socket socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            //

            ncConfigBLL objConfiguracaoBLL = new ncConfigBLL();
            ncConfiguracao objConfiguracao = new ncConfiguracao();
            objConfiguracao = objConfiguracaoBLL.ConsultaServidor(objSessao);
            EndPoint endPoint;

            if (string.IsNullOrWhiteSpace(objConfiguracao.ServidorAplicacaoIP) || objConfiguracao.ServidorAplicacaoPorta < 0)
                endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 0);
            else
                endPoint = new IPEndPoint(IPAddress.Parse(objConfiguracao.ServidorAplicacaoIP), objConfiguracao.ServidorAplicacaoPorta);

            //

            byte[] mensagem = Encoding.Default.GetBytes("<NCAC_OPERADOR" + objSessao.SessionID.ToString().PadRight(100, ' ') + ">");

            socketSend.SendTo(mensagem, mensagem.Length, SocketFlags.None, endPoint);
        }

I tried use ajax, javaScript and a lot of things to call but all without success. I hope that somebody can help me!

Just to dont appears doubts below I will put my all Default.aspx.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Project.Web.Default" %>

<%@ Import Namespace="System.Threading" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Project</title>
    <style type="text/css">
        html, body
        {
            height: 100%;
            overflow: hidden;
        }
        body
        {
            padding: 0;
            margin: 0;
        }
        #silverlightControlHost
        {
            height: 100%;
            text-align: center;
        }
    </style>
    <script language="javascript" type="text/javascript">
        window.onbeforeunload = function () {
        }
    </script>
    <script type="text/javascript" src="Javascript\Nitgen.js"></script>
    <script type="text/javascript" src="Silverlight.js"></script>
    <script type="text/javascript">
        function onSilverlightError(sender, args) {
            var appSource = "";
            if (sender != null && sender != 0) {
                appSource = sender.getHost().Source;
            }

            var errorType = args.ErrorType;
            var iErrorCode = args.ErrorCode;

            if (errorType == "ImageError" || errorType == "MediaError") {
                return;
            }

            var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n";

            errMsg += "Code: " + iErrorCode + "    \n";
            errMsg += "Category: " + errorType + "       \n";
            errMsg += "Message: " + args.ErrorMessage + "     \n";

            if (errorType == "ParserError") {
                errMsg += "File: " + args.xamlFile + "     \n";
                errMsg += "Line: " + args.lineNumber + "     \n";
                errMsg += "Position: " + args.charPosition + "     \n";
            }
            else if (errorType == "RuntimeError") {
                if (args.lineNumber != 0) {
                    errMsg += "Line: " + args.lineNumber + "     \n";
                    errMsg += "Position: " + args.charPosition + "     \n";
                }
                errMsg += "MethodName: " + args.methodName + "     \n";
            }

            throw new Error(errMsg);
        }
    </script>
    <script language="javascript" type="text/javascript">
        function returnString() {
            return screen.height;
        }
    </script>
</head>
<body>
    <form id="form1" runat="server" style="height: 100%">
    <div id="silverlightControlHost">
        <object data="data:application/x-silverlight-2," type="application/x-silverlight-2"
            width="100%" height="100%">
            <param name="source" value="ClientBin/Project.xap" />
            <param name="onError" value="onSilverlightError" />
            <param name="background" value="white" />
            <param name="minRuntimeVersion" value="5.0.61118.0" />
            <param name="autoUpgrade" value="true" />
            <param name="uiculture" value="<%=Thread.CurrentThread.CurrentCulture.Name %>" />
            <!--Por Eduardo: Linha implementa Literal Class para reserva de texto estático na web.page -->
            <asp:Literal ID="ncInitParam" runat="server"></asp:Literal>
            <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" style="text-decoration: none">
                <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight"
                    style="border-style: none" />
            </a>
        </object>
        <iframe id="_sl_historyFrame" style="visibility: hidden; height: 0px; width: 0px;
            border: 0px"></iframe>
    </div>
    </form>
</body>
</html>

THANK YOU!!

All replies (6)

Tuesday, February 18, 2014 8:14 AM ✅Answered

Short Answer : There is no reliable way to handle this.

When your browser closes, it is purely a client-side event that has nothing to do with your server-side code and will trigger no events to indicate that the browser was closed. So even if you were able to call your server-side could through an AJAX call or otherwise, you have no guarantee that your Database-related or server-side code would be executed.

When the browser is closed, you aren't really going to be able to capture any server-side code (since actually closing the browser is a client-side operation) however there is a Javascript event that is called prior to a window closing called onbeforeunload which can fire a Javascript function when the browser is about to be closed : 

<script type='text/javascript'>
    //Maps an event to the window closing event
    window.onbeforeunload = function(e) {
        alert("The Window is closing!");
    };
</script>

However, this event as mentioned is handled purely client-side and so you aren't really going to be able to handle any server-side operations within your code-behind and will have no guarantee that the code is going to be executed.


Tuesday, February 18, 2014 2:57 PM ✅Answered

$``(``window``).``on``(``'beforeunload'``,`` ``function``()`` ``{
    ``var`` x ``=``logout``();
    ``return`` x``;
});
function`` logout``(){`` jQuery``.``ajax``({
        ``});
        ``return`` `` ``1``+``3``;
}

this works on Chrome.

Just to let you know, You can not catch a close event 100%.

there is work around to do something you just said,

call js function logout() onbeforeunload, in logout()

force this > window.location = "../../Logoff.aspx";

and in logoff.aspx page_load, do your stuff. 


Tuesday, February 18, 2014 12:30 PM

Rion thank you for answer!!

I know that this event just occurs on client-side...thinking this I will execute the code behind of Default.aspx to send a socket UDP to my server-side to exclude the current operador logged.

But I need help to call the C# method (aspx.cs) from aspx to send the socket to the server to remove the current operador using session ID.

And I read that have differences between IE and Chrome....the onbeforeunload doesnt work on Chrome. How can I solve this?

[EDIT]Could you indicate another way to do this? Remove a online user when browser close? [/EDIT]


Tuesday, February 18, 2014 3:38 PM

As mentioned, there are ways to attempt to work around this (such as attempting to navigate the user to another page to handle the logic or making an AJAX call) but you cannot guarantee that your server-side code will execute and "log off" your user properly in all browsers.

One consideration that you might want to try would be decreasing the duration for your authentication cookie (if you are using Forms Authentication). This will essentially log your user out if they have not been active within the application past the duration of your timeout, which if set to a small value will likely expire prior to the user returning to the application.


Tuesday, February 18, 2014 5:12 PM

like Rion and I mentioned, you can not catch 100% close event from client side. So you cant 100% log off a user base on when they close the browser.

i think 95% is the best you can do, really depends on your users actions.

If you want to use other way to log off your inactive user, Rion provide you a simple solution.

You can also do it through the Database, or 3rd party monitor software. but those are a lot effort compare to just a configuration change. 


Thursday, February 20, 2014 8:04 AM

I have a Silverlight Application that works with WCF Services.

I create a static list on my server-side that when the user enter I add this user. While the user be online I will send "DateTime.NOW" to update my static list based on SessionID of user.
And when the user close the browser, this user is still on the list, but after logoff the list will not update any more and in the next login I will check the last date time and remove all users that doesnt update the date time.

Is simple...thanks for help Rion William and Tipone !!