Thursday, February 4, 2010

Base Page For Detecting Session Timeout in ASP.Net/C#

In this tutorial we will be going over how to create a base page class to handle your sessions. The number one question I get asked time and time again is how to manage sessions, and how to detect if a session has expired. Back in the days before .Net things were a little more complicated when it came to solving this riddle, but with the advent of the .Net Framework 2.0 a new class was introduced, the HttpSessionState Class, which is a member of the System.Web.SessionState Namespace. The new HttpSessionState Class gives us access to session state items and other lifetime management methods.

One of the items in the HttpSessionState class we will be looking at is the IsNewSession Property. This property lets us know whether the current session was created wtih the current request, or if it was an existing session. This is invaluable as we can use it to determine if the users session had expired or timed out. The IsNewSession Property is more robust and advanced then simply checking if the session is null because it takes into account a session timeout as well.

In this tutorial we will create a base page class that we can inherit all our pages from, and in this class we will check the status of the users session in the Page.OnInit Method. The OnOnit Method fires before the Page Load Event, giving us the ability to check the session before the page is actually rendered. So lets get to some code.

The first thing we will need to do, as with any class you create, is to make sure we have a reference to the appropriate Namespaces. For our class we need but 2 Namespaces, the System.Web.UI Namespace and the System Namespace, so lets add them to our class.

NOTE: All Namespace references need to come before the declaration of your class.

using System;
using System.Web.UI;

Now we are going to declare our class, the class in this example is named SessionCheck, and it looks like

public class SessionCheck: System.Web.UI.Page
{

}

You will notice that our base class, which we will be inheriting from, inherits from the System.Web.UI.Page class. Doing this gives us access to all the methods, properties and events of the Page  class. In our base class we will have a single property, this will be the property that will hold the URL we want the user to redirect to if there is a problem with their session. We make this property static  so we can access it without having to create an instance of the class. We dont want to have to do this because we are inheriting from it. 
This is our property


/// 
/// property vcariable for the URL Property
/// 
private static string _url;

/// 
/// property to hold the redirect url we will
/// use if the users session is expired or has
/// timed out.
/// 
public static string URL
{
    get { return _url; }
    set { _url = value; }
}
Now that we have our property out of the way, we will look at the only of our base class, the OnInit which we will override in order to add our ow functionality. In this method we will also initialize our base class, you do that with line
base.OnInit(e);
In our OnInit Method we will first check to see if the current session is null. If the session is null we then will check the IsNewSession Property to see if this session was created in this request. If we determine the session is a new session, we will then cal upon the Headers Property of the HttpRequest Class, which is located in the System.Web Namespace. In our OnInit Method we will first check to see if the current session is null. If the session is null we then will check the IsNewSession Property to see if this session was created in this request. If we determine the session is a new session, we will then cal upon the Headers Property of the HttpRequest Class, which is located in the System.Web Namespace. The Header we are retrieving is the Cookie Header. Once we have this, we will first check to see if it's null, if it's not null we will look for the value ASP.Net_SessionId. Now if we make it this far, and that cookie exists, we know the session has timed out, so we will then redirect the user to our redirect page, which is set with the URL Property. So lets take a look at our new OnInit Method:
override protected void OnInit(EventArgs e)
{
    //initialize our base class (System.Web,UI.Page)
    base.OnInit(e);
    //check to see if the Session is null (doesnt exist)
    if (Context.Session != null)
    {
        //check the IsNewSession value, this will tell us if the session has been reset.
        //IsNewSession will also let us know if the users session has timed out
        if (Session.IsNewSession)
        {
           //now we know it's a new session, so we check to see if a cookie is present
            string cookie = Request.Headers["Cookie"];
            //now we determine if there is a cookie does it contains what we're looking for
            if ((null != cookie) && (cookie.IndexOf("ASP.NET_SessionId") >= 0))
            {
                //since it's a new session but a ASP.Net cookie exist we know
                //the session has expired so we need to redirect them
                Response.Redirect("Default.aspx?timeout=yes&success=no");
            }
        }
    }
}
That's it, we have completed our base class which all our web forms will inherit from, allowing us to keep an eye on the users session. Now that we have the class completed we need to use it. Before it can be affected we need to do 1 of 2 things
  • Add EnableSessionState = true to the @Page directive on all pages that will inherit from our base class or
  • Add the following line to the section of our web.config file:
That's it, we have completed our base class which all our web forms will inherit from, allowing us to keep an eye on the users session. Now that we have the class completed we need to use it. Before it can be affected we need to do 1 of 2 things
  • Add EnableSessionState = true to the @Page directive on all pages that will inherit from our base class or
  • Add the following line to the section of our web.config file



Number 2 on that list will enable session state on all pages in the web. If you dont access session items in each of your pages, this might be overkill. Next we will need to inherit from our base class. Doing this will give our web form the following declaration

public partial class _Default : SessionCheck
{

}

Then in the Page_Load Event we will set the redirect URL for our base class
protected void Page_Load(object sender, EventArgs e)
{
    SessionCheck.URL = "Default.aspx";
}

Now here is the entire base page in its entirety
//   A Base Page class for detecting session time outs
//
//   This program is free software: you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation, either version 3 of the License, or
//   (at your option) any later version.
//
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program.  If not, see .
//*****************************************************************************************

using System;
using System.Web.UI;

/// 
/// This is a custom "base page" to inherit from which will be used
/// to check the session status. If the session has expired or is a timeout
/// we will redirect the user to the page we specify. In the page you use
/// to inherit this from you need to set EnableSessionState = True
/// 
public class SessionCheck : System.Web.UI.Page
{
    /// 
    /// property vcariable for the URL Property
    /// 
    private static string _redirectUrl;

    /// 
    /// property to hold the redirect url we will
    /// use if the users session is expired or has
    /// timed out.
    /// 
    public static string RedirectUrl
    {
        get { return _redirectUrl; }
        set { _redirectUrl = value; }
    }

        public SessionCheck()
        {
        _redirectUrl = string.Empty;
        }

    override protected void OnInit(EventArgs e)
    {
        //initialize our base class (System.Web,UI.Page)
        base.OnInit(e);
        //check to see if the Session is null (doesnt exist)
        if (Context.Session != null)
        {
            //check the IsNewSession value, this will tell us if the session has been reset.
            //IsNewSession will also let us know if the users session has timed out
            if (Session.IsNewSession)
            {
               //now we know it's a new session, so we check to see if a cookie is present
                string cookie = Request.Headers["Cookie"];
                //now we determine if there is a cookie does it contains what we're looking for
                if ((null != cookie) && (cookie.IndexOf("ASP.NET_SessionId") >= 0))
                {
                    //since it's a new session but a ASP.Net cookie exist we know
                    //the session has expired so we need to redirect them
                    Response.Redirect("Default.aspx?timeout=yes&success=no");
                }
            }
        }
    }
}

And there you have it, a custom base class that you can use to detect session timeouts. I hope you found this tutorial helpful and useful, and thank you for reading :)

Happy Coding!

1 comment:

  1. The code is really good, just that the checking of Cookie is not compulsory as through IsNewSession property itself implies that the current session is no more...!

    Thanks Any ways, it's very useful...!

    ReplyDelete