Home
    Shop
    Advertise
    Write For Us
    Affiliate
    Newsletter
    Contact

How to find if ASP.NET session is expired

Session data should persist during single visit. The problem in ASP.NET is that we don't know exactly when certain visit ends. HTTP is known as stateless protocol, which means that we can't know for sure if request comes from new or existing visitor. We can't know is visitor closed its browser or just minimized it while is doing something else. To simulate maintaining of state in stateless protocol, ASP.NET writes session cookie on client's machine. Session cookie contains unique identification key, named session id. So, that session id, in form of plain string, is only thing that ASP.NET application uses to "recognize" the visitor.

 

Because ASP.NET has no idea when visitor closes its web browser, it uses Session.Timeout property to decide, or better say guess, when visit will finish. If visitor doesn't make new request during time longer than Session.Timeout (it is 20 minutes by default), session will be deleted. When that happens, we say that session is expired. This sounds good in theory, but in real world someone could close a browser after a minute. In that case keeping session is useless. Some other visitor could go to lunch break or take a long phone call and later try to continue "visit". For both cases, ASP.NET will react on same way. It will delete session after 20 minutes of inactivity.

The problem could occur if visitor is in the middle of long task, like filling of long order form or reading license agreement before placing an order for your product. Session expiration could cause that he or she must start from the beginning which could be very frustrating. More about how to solve problems like these and how to artificially keep session alive you can find in How To Keep ASP.NET Session Alive tutorial.

In the other hand, session expiration has its use in highly secure applications, like online banking systems. Applications that work with money transactions often have very short session timeout (5 minutes or even less). Of course, this is also annoying for users but bankers probably think that is much worse if someone spend all money from your account because you forget to log out.

If session is expired, instead of some unpredictable error, you should inform visitor what happened and what can be done. That could be implemented on next request when application will redirect browser to some Your-Session-Is-Expired.aspx page, or you can redirect browser automatically after session timeout using JavaScript code or HTML meta refresh.

Session.IsNewSession property

Session.IsNewSession property tells us if session is created during current request or not. If value is true, it is a new session. If value is false, it is existing active session created before.

But, there are two types of "new" sessions. First is new session created when new visitor comes to website. Second type is session which is created because previous session expired. If visitor is not made any request longer than specified in Session.TimeOut property (20 minutes by default), session will expire. But, IsNewSession property can't distinct these two cases.

The same worth for checking value of some session variable. You can try to place some value in session variable and check it later to see if variable is empty. Something like this:

[ C# ]

if(Session["UserID"] == null)
{
   // This variable not exists, so it is new session or expired session
}
else
{
   //Session variable exists, so it is active visitor
}

[ VB.NET ]

If Session("UserID") Is Nothing Then
   ' This variable not exists, so it is new session or expired session
Else
   ' Session variable exists, so it is active visitor
End If

As you see, like IsNewSession property, this code can't say is it new visitor with fresh session, or existing visitor with expired session. It can tell us only if session collection is already existing, but can't say is it expired or not.

How to check if session is expired using ASP.NET code

We'll define expired session as situation when Session.IsNewSession is true (it is a new session), but  session cookie already exists on visitor's computer from previous session. Here is a procedure that returns true if session is expired and returns false if not.

[ C# ]

public static bool IsSessionExpired()
{
  if (HttpContext.Current.Session != null)
  {
    if (HttpContext.Current.Session.IsNewSession)
    {
     string CookieHeaders = HttpContext.Current.Request.Headers["Cookie"];

     if ((null != CookieHeaders) && (CookieHeaders.IndexOf("ASP.NET_SessionId") >= 0))
     {
     // IsNewSession is true, but session cookie exists,
     // so, ASP.NET session is expired
     return true;
     }
   }
  }

  // Session is not expired and function will return false,
  // could be new session, or existing active session
  return false;
}

[ VB.NET ]

Public Shared Function IsSessionExpired() As Boolean

 If HttpContext.Current.Session Is Nothing Then
   If (HttpContext.Current.Session.IsNewSession) Then

    Dim CookieHeaders As String = HttpContext.Current.Request.Headers("Cookie")

     If IsNothing(CookieHeaders) And (CookieHeaders.IndexOf("ASP.NET_SessionId") >= 0) Then
        ' IsNewSession is true and session cookie exists,
        ' so, ASP.NET session is expired
        Return True
     End If
   End If
 End If

 ' Session is not expired and function will return False,
 ' it could be new session, or existing active session
 Return False
End Function

You can place this function on page if you need it in single file. If you need it on every page of website, consider placing function in separate class and then save class in App_Code folder, so you can call it from any place.

Another option is to create base page class with this function included, and then inherit all pages from that base page. Sometimes this could be complex if you have existing website with large number of pages. One more option is to use master page.

If IsSessionExpired() function returns true, you can do appropriate action, like show a message in label control which informs user that session is expired, redirect user to some SessionExpired.aspx page etc.

Check if session is expired using Global.asax file

Another option to check if session is expired is by using Session_Start event in Global.asax file. When Session_Start procedure executes, that already means that new session is created. So we don't need to check IsNewSession value like in previous example. Here, we need only second condition i.e. to see if session cookie exists.

Code in Global.asax that checks if session is expired could look like this:

[ C# ]

void Session_Start(object sender, EventArgs e)
{
 string CookieHeaders = HttpContext.Current.Request.Headers["Cookie"];

 if ((null != CookieHeaders) && (CookieHeaders.IndexOf("ASP.NET_SessionId") >= 0))
 {
   // It is existing visitor, but ASP.NET session is expired
 }
 else
 {
   // It is a new visitor, session was not created before
 }
}

[ VB.NET ]

 Protected Sub Session_Start(ByVal sender As Object, ByVal e As System.EventArgs)

   Dim CookieHeaders As String = HttpContext.Current.Request.Headers("Cookie")

   If IsNothing(CookieHeaders) And (CookieHeaders.IndexOf("ASP.NET_SessionId") >= 0) Then
     ' It is existing visitor, but ASP.NET session is expired
   Else
     ' It is a new visitor, session was not created before
   End If
End Sub

As you see, using of Global.asax requires less code than first example. Also, it is a lot of faster and easier to write this short code to Global.asax, than to implement base page or master pages on website. If your website has a lot of pages, and you don't use master page already, it could be huge task to relate master page to each .aspx page, or even worse to inherit all pages from newly created base page.

In the other hand, if you need to check if session is expired only on few pages, not in complete website, then is justified to use master page or even create base page.

Using Session_End event to know when session expires

Logical question is why not use Session_End event to know when session expires. This event theoretically fires when session expires. Then why previous example uses Session_Start? The main problem with Session_End is that you can't use HttpContext.Current inside of this procedure. That means that you can't redirect visitor to Your-Session-Is-Expired.aspx page or do anything else to inform visitor that session is expired. Since session is expired, in Session_End you don't have possibility of any communication with visitor. That narrows options and possible uses of this method.

In addition to this, Session_End event will work only if default InProc mode is used. Session_End will not work if sessions are stored on SQL Server, State Server or if custom session provider is used. In SQLServer, StateServer and Custom modes, you can use only Session_Start and Session_End is simply not fired. More about different session state modes you can read in ASP.NET Session State Modes Explained tutorial.

One possible options where you can use Session_End is to do tasks that not affect visitor's browser, like execute some internal code or SQL stored procedure to analyze data or clean up when session expires etc.

How to automatically redirect visitor after session is expired

In previous examples, session expiration check comes when visitor makes new request. Instead of waiting for that new request, you can redirect visitor automatically immediately after session is expired. In this case, you don't wait until visitor does any action. Browser will automatically load Your-Session-Is-Expired.aspx page after session timeout. This could be useful because of security reasons where data are highly sensitive, like in online banking application. If you accidentally forget to log out from application, session will expire. By using automatic redirection, someone else will not see your data, but only "session expired" screen.

There is an option to use JavaScript for automatic redirection, but simpler method is to use HTML meta refresh. For example, if session timeout is 20 minutes, meta refresh will redirect visitor after 21 minutes to Your-Session-Is-Expired.aspx page. On target page, you can inform visitor that session is expired due to security reasons and provide additional information. Code implementation inside <head> tag could look like this:

<meta http-equiv="refresh" content="21;url=/Your-Session-Is-Expired.aspx" />

In this case, meta refresh time is hard coded. More flexible version with server side code would be:

[ C# ]

Response.AppendHeader("Refresh", "\""
   + Session.Timeout.ToString()
   + ";url=/Your-Session-Is-Expired.aspx");

[ VB.NET ]

Response.AppendHeader("Refresh", """" _
   & Session.Timeout.ToString() _
   & ";url=/Your-Session-Is-Expired.aspx")

This code will dynamically read Session.Timeout value and write correct meta refresh tag to redirect visitor when its session is expired.

As I said earlier, another option is to use JavaScript's setTimeout function to execute some procedure after session expires. That could be redirection with JavaScript code, but using meta refresh is simpler for that. Using of setTimeout method is justified if you need to inform user before session expires. In that case, you can show a dialog box and offer a possibility to refresh the page to keep session alive.

Remarks

Session expiration is useful process that saves server's resources and helps avoid possible security problems. In some cases, for example if user needs to fill long form, survey etc., we want to keep session alive. There is an option to increase session timeout, but on that way server will keep all sessions, including sessions of inactive users who closed their browsers. Much scalable way is to use client side code, so only users with opened browsers will have live sessions. More about how to keep sessions alive you can find in How To Keep ASP.NET Session Alive tutorial.

Also, sessions are not answer in every scenario, especially if you need to maintain state during multiple visits. More about different options you can use when sessions are not good enough, read in ASP.NET Session State Alternatives tutorial.

Happy coding!


Tutorial toolbar:  Tell A Friend  |  Add to favorites  |  Feedback  |   


comments powered by Disqus