Apr 15

There are a multitude of ways to implement Session Variables but developers need know when to use them, a full-proof way on how to minimize errors, and then a good way to implement them which minimizes code written. This article is meant to address these issues.

Some say: Cookies "Good", Session Variables "Bad"

This is only true in some scenarios, when there is a need to have variables which are global in scope for a user's session which do not hold sensitive information. Sensitive information would be something like user logins and passwords, and any information that maybe part of a secure site (https). Also, if your site is using a database all these variables should be kept there, there are ways on the db side which can be implemented to secure this sensitive information even further. In addition, the use of session variables increases the overhead on the server and cookies reduce this overhead, especially on large sites with a multitude of users.

So when should session variables be used? Well, when a database is unavailable, when there is a need to keep private information private and to be able use this information globally throughout the site for the user's session.

How Not To Implement Session Variables

Many sites have implemented a poor method of using session variables mainly, because it was easy and not much thought given to the impact of this implementation down the road. Here is a common way, but a poor way of implementing the use Session Variables:

// Poor Implementation: Writing to a session variable
Session["Password"] = strSomeTextBox.Text;
        
// Poor Implementation:  Reading from a session variable
string strPassword = Session["Password"].ToString();

Although, the syntax is correct, this implementation is just asking for trouble. Ok, now the site has grown to ~100 pages, ask the questions:

  • How many session variables are in use?
  • What are they?
  • and... How many times have you seen the 'NullReferenceException' error when debugging?

This drives a point home, huh...

 

Implementing Session Variables with Class

This method will implement 2 new classes. The first one will be a simple, static, shared class which will keep track of all the session variables used and avoids the 'NullReferenceException' errors. The second class is one that will override the default Page class, it will test the condition if the session is still valid, and if not, provide an elegant way to inform the user the session has expired (because in IIS, the session expires after 20 minutes as a default, so there is a need to trap and handle this condition).

Below is our static, shared class, named mySessionVar, which we will save as mySessionVaribles.cs in the [App_Code] folder, off the root folder. By reviewing the code, you can now see how many session variables are in use, and a full proof way to avoid the dreaded 'NullReferenceException' errors.

public static class mySessionVar
{ // Declare the session state variable: to determine if the session is still valid
  private static string _strValidSession = "strValidSession";

  // Start the list of all the site's Session Variables.............
  private static string _strPassword = "strPassword";
        
  public static string strValidSession
  {
    get
    { // Test for null
      if (HttpContext.Current.Session[mySessionVar._strValidSession] == null)
      { // If so, return an empty string
        return string.Empty;
      }
      else
      { // not null, return the value
        return HttpContext.Current.Session[mySessionVar._strValidSession].ToString();
      }
    }
    set
    { // assign the session variable with the value
      HttpContext.Current.Session[mySessionVar._strValidSession] = value;
    }
  }

// NOW: Start defining all the site's Session Variables.............
  public static string strPassword 
  {
    get
    { // Test for null
      if (HttpContext.Current.Session[mySessionVar._strPassword] == null)
      { // If so, return an empty string
        return string.Empty;
      }
      else
      { // not null, return the value
        return HttpContext.Current.Session[mySessionVar._strPassword].ToString();
      }
    }
    set
    { // assign the session variable with the value
      HttpContext.Current.Session[mySessionVar._strPassword] = value;
    }
  }

}

Now, the syntax to read and write a session variable defined in the class shown above is:

// The better method: Writing to a session variable
mySessionVar.strPassword = strSomeTextBox.Text;
        
// The better method: Reading from a session variable
string strPassword = mySessionVar.strPassword;

Below is our second class which we will use to override the default Page class (System.Web.UI.Page), named myBasePage and we will save it as myBasePage.cs in the [App_Code] folder, off the root folder. This is to handle the condition when the session expires.

public class myBasePage : System.Web.UI.Page
{
  override protected void OnInit(EventArgs e)
  {
    base.OnInit(e);

    if (mySessionVar.strValidSession.Length == 0)
    {
      Response.Redirect("../SessionExpired.htm");
    }
  }
}

Now we'll implement this by using the following on all our .Net Pages, now, if the session times out the user will be redirected (without error) to the SessionExpired.htm page:

public partial class pgSomePage : myBasePage
{
  // your code...
}

instead of this, the Page default

public partial class pgSomePage : System.Web.UI.Page
{
  // your code...
}

Now, you are all done... !

Oh, Your Site is still using Frames, Response.Redirect() isn't Working Correctly?

You need to clear the screen and bust out of the frames, well, switch over to MasterPages... No, just kidding!

We'll just add another step to the redirection. First, we'll hide this page (SessionExpired.htm) by not displaying any content but use this page to break-out of the FrameSet and use javascript's function: window.open('../FramesExpired.htm', '_top') which redirects to the page FramesExpired.htm, and use this page to denote that the Session expired. Here is the code for SessionExpired.htm within the Frameset environment:

<HTML>
<HEAD>
<script LANGUAGE='JavaScript' TYPE='text/javascript'> 
{
  window.open('../FramesExpired.htm', '_top') 
}  
</script>
</HEAD>
<BODY></BODY>
</HTML>
Important Note:  If your site is using frames you still need to use the Response.Redirect() even though it does not have any other parameters which would bust out of the frameset. Each frame is similar to another browser session, the server does not know about the other frames, but on the client side that a different story and that is where client-side script comes into play.

Well, if you did use Response.Write() to send that javascript code to the client to redirect and bust out of the frames, that code will not fire first. The Page_Load() will fire after OnInit(), and you will probably be using some session variables in Page_Load(), thus causing errors because they expired. The use of Response.Redirect() will halt further processing (preventing Page_Load() from firing) and only redirect to the chosen page.

Hope this helps!

the WebPepper team