Handling Session Timeout

I was asked to elegantly handle Session Timeout in our application and was directed to the linked article at Nikhil Kolthari’s blog .

Nikhil provides two fully-coded examples of handling Session Timeout. The second example works brilliantly, the first example does not work at all.

This Works

Here is Nikhil’s Session Expiry detection code that works:


protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (Context.Session != null)
{
//check whether a new session was generated
if (Session.IsNewSession)
{
//check whether a cookies had already been associated with this request
HttpCookie sessionCookie = Request.Cookies["ASP.NET_SessionId"];
if (sessionCookie != null)
{
string sessionValue = sessionCookie.Value;
if (!string.IsNullOrEmpty(sessionValue))
{
// we have session timeout condition!
// Response.Redirect("SessionTimeout.htm");
Session["IsSessionTimeOut"] = true;
}
}
}
}
}

Why it works

The first time you put anything into Session State, ASP.NET creates the Session cookie called ASP.NET_SessionId. When Session Timeout occurs the ASP.NET_SessionId cookie is deleted BUT the Session itself is not. Provided the user does not close their browser, ASP.NET will recycle the Session but using the same SessionId as soon as the user sits down at their browser and starts using the expired Session again. Session.IsNewSession is true for the recycled Session, the SessionId still belongs to the same user (they didn’t close their browser) but the State within that Session, which is contained in the cookie ASP.NET_SessionId, has expired and is hence null.

That’s why checking for Session.IsNewSession and ASP.NET_SessionId = false detects an expired session.

NB: As Nikhil says, the above code depends on having Session_Start wired up in Global.asax.

This Doesn’t Work

Here is Nikhil’s example which doesn’t work.


First, in Global.asax, create your own GUID and put it in the session object,

void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
Session["CustomSessionId"] = Guid.NewGuid();
}

Second, BasePage.cs which would have inherited Page, in PageLoad() event, check whether the Session["CustomSessionId"] == null, if it IS null, it means that the session was timed-out and AspNet runtime cleared it out.

if( Session["CustomSessionId"] == null)
{
Response.Redirect("TimeoutPage.htm");
}

Why It Doesn’t Work

On Session timeout, Session State is discarded. As soon as the user becomes active in the timed-out Session, the SessionId is recycled, Session_Start is invoked and “CustomSessionId” will be re-initialised. This means “CustomSessionId” will never be null and thus the Session timeout condition in BasePage.cs will never be true.

Use the other example that Nikhil provides. It works. Thanks Nikhil for the tip. You saved me heaps of work!

Advertisements

Tags:

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: