Click here to Skip to main content
Click here to Skip to main content

Detect browser closing through clicks on the [X] button

, 23 Jun 2005
Rate this:
Please Sign up or sign in to vote.
This explains the technique to detect Window closing with C# and how to close user sessions safely at the same time.

Introduction

I had been searching through the internet to find out how to control this issue: You have a web application where you validate every user that logs in, if somebody tries to log in from another place with the same user name, he should be denied access because the user is at the system right at that moment.

Well, the way I'm controlling this, is using a table where I put all the users’ info. I’ll make this simple. Look at the following example:

Table : employee
-------------------
username
password
active

Notice that if the user logs in the application, the field "active" will turn to 1… if the user logs off, the field will turn to 0.

Well ... I have this web application where I have a button to sign out. When I press the button, it invokes a function to update my database to turn “active”=0, but the problem is what if I press the X button of the navigator? I mean, there’s no way to detect using C#, how to catch when I close the browser in order to update the database, right? Everyone told me that the event onUnload (C#) works for detecting it… wrong! This event is not triggered when I close the window but it does when I browse another web page. So it doesn't help me. Others told me that Global.Asax catches a window closing with Session_End.. Wrong! Global.Asax works only when you tell the application to end or when the session expires … Believe me.. I tried a lot of things…

Well I guess I have found a solution to this problem… I took a long time searching though the internet looking for something until I got this link and based on the answer provided in that link, I decided to do this. I have Login.aspx, RETURN.aspx (it has three pages, too, left and principal, it's a frames page…) and the spyWin.aspx , (special thanks to PE_CF_DEV from experts-exchange for the code, I just took your code and mixed it with C#). Work with two session variables, one to save the user login (Session[“USER”]) and the other to check if it's the right moment to update the database (Session[“RETURN”]).

  1. In your login page …login.aspx, you have to put this in the LOAD event:
    if ( Convert.ToString(Session["USER"]).Length > 0 )
    {
        if (Session["RETURN"]!=null)
        {
            if ( Convert.ToInt32(Session["RETURN"]) == 1)
            {
                Session["RETURN"] = 0;
                …<Code to reset database>…
            }
            else
            {
                Response.Redirect("RETURN.aspx",false); 
            }
        }
    }

    This will first check if I had logged in recently, if the session is still alive and is trying to enter at Login.aspx, it will be redirected to RETURN.aspx.

  2. Put this code in the pressed event of the button to log out (this button is located in the left frame):
    Session.Abandon(); 
    Response.Write("<script>javascript: parent.opener=''; " + 
                                    "parent.close();</script>");

    The first line closes the session, this is caught by the event Session_end of GLOBAL.ASAX.

    protected void Session_End(Object sender, EventArgs e)
    {
        if ( Convert.ToString(Session["USER"]).Length > 0 )
        {
            <… Your code to update database>
            Session["USER"] = null;
        }
    }

    The second one, invokes a JavaScript event to close the window. Usually the browser detects when you close it, it sends you a message (message “do you want to close this window?”). The next point will solve this so that no message window appears.

  3. Put this in the LOAD event of RETURN.aspx (not the pages that form the frames page, I mean, not the left, top, or the principal page).
    if (Session["USER"]==null)
    {
        Response.Redirect("Login.aspx",false);
    }
    else { Session["RETURN"] = 0; }

    This will be validated if there's still a user with an active session. I’ll explain a little later, the use of Session["RETURN"].

    At the moment, I can only say that this session variable is initialized.

  4. Put this in the HTML section (in the <HEAD> ) of Index.aspx ( not the pages that form the frames page, I mean, not the left, top, or the principal page).
    <script language="javascript">
    function launch_spyWin() 
    {
        spyWin = open('spyWin.aspx','spyWin',
           'width=100,height=100,left=2000,top=0,status=0');
        spyWin.blur();
    }
    onunload = launch_spyWin;
    </script>

    This will solve the point explained in step 2). My code is based on the code from PE_CF_DEV.

  5. With JavaScript we know that the event “onUnload” will run the function regardless of the page being closed or the user navigating to another page. OK, now write this in the LOAD event of spyWin.aspx.
    if (Convert.ToInt32(Session["RETURN"])==0)
    {
        Session["RETURN"] = 1 ;
        
        string script = "<script type='text/javascript' " + 
                "language="'javascript'"> " +
                " function check_opener() { " +
                " if (opener && opener.closed){ " +
                " parent.opener=''; " +
                " parent.close(); " +
                " window.open('Login.aspx') " +
                " } " +
                " else{ " +
                " parent.opener=''; " +
                " parent.close(); " +
                " } " +
                "} " +
                " onload = function() { " +
                " self.blur(); " +
                " setTimeout('check_opener()',0); " +
                " } " +
                " </script>";
        this.Controls.Add(new LiteralControl(script));
        
    }
    else
    {
        Session["RETURN"] = 0 ;
    }

    This spyWindow is a non-visible popup window that will be triggered when the main window is closed. When I change Session["RETURN"] = 1, the Login.aspx catches this variable and then updates the database (the same function of Session_End of Global.asax)..

Problem solved! Now my life is easier...

Hope this helps someone…

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

Share

About the Author

Mario Serrano (makadown)
Web Developer
Mexico Mexico
Mario Serrano is a C# Developer from Mexicali , Baja California. Coding for food...
 
He was working for Baja California´s Government, developing with Power Builder and Oracle Databases. Now He's currently learning more with C# in his actual job and willing to increase knowledge about .NET Big Grin | :-D .

Comments and Discussions

 
Generaltry this it will help u more Pinmembersantosh d25-Mar-10 19:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140814.1 | Last Updated 23 Jun 2005
Article Copyright 2005 by Mario Serrano (makadown)
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid