How to use untyped Session Variables

Session variables are helpful, of course, but they have many drawbacks, including having to access them by name in a string (no intellisense, no compile time error checking), they’re untyped, so you have to cast them, and it’s easy to accidentally use the same name from different pages for different purposes and overwrite their contents, creating odd runtime behavior that’s nearly impossible to track down.  (BTW, this works for application variables too, of course).

Click here to follow me on Google+.

In this article, I’ll provide simple techniques to completely eliminate ALL of these problems.

Accidental reuse of the same name

Take this session variable as an example:

Session["SomeEventTime"] = DateTime.Now;

Imagine two developers (or even ONE developer… I’ve done this myself) working on 2 pages of the same app at the same time.  The app may have timestamps that it needs to track.  It’s not uncommon for 2 programmers who work together to come up with the same name for their own session variables.  When a user runs the app and uses one page that sets the variable, then visits the other page, that resets it, then any code that depended on the first one will behave poorly.

Typos of the name

Take this example:

Session["SomeEventTime"] = DateTime.Now;
this.EventTimeLabel.text = ((DateTime)Session["SomEvenTime"]).ToString();

Notice the error?  On the second line, the “e” in “Some” is missing and the “t” in “Event” is missing.  The compiler won’t catch this.  It’ll only be caught at run time and likely by the customer, which is embarrassing and gives both you and your team a negative image and increases the cost to the customer because you’ve got to go back in and fix it.

Notice also that you don’t get intellisense with session variable names like you do with components and other variables?  You just have to know that the session variable exists, what its name is, and what type of data is stored in it.  There’s no catalog or anything at all to know what session variables are used.  You just have to be extremely diligent, search the source for use before you make up a new one, do this 100% of the time, and hope that the other developers on your team are also doing this, diligently, 100% of the time.  Chances of that happening?  Nearly zero.

Untyped

Notice also that the compiler has no idea what type of object is stored in the session variable?  In C#, you have to cast it, which means you have to just “know” what’s in there, and if you’re wrong, the compiler won’t know… It’ll just accept it, compile it, and then it’ll crash at run time.  VB.Net doesn’t require you to cast it, but same runtime problem.  If you assign it to a variable of the wrong type, the compiler won’t catch it, will compile it, and your customers will find the runtime error.

Solutions!

Here’s how to resolve each of these problems:

Accidental reuse of the same name

This one’s easy, but apparently not obvious to most programmers until it’s pointed out to them.  Let’s see if you can figure it out before I tell it to you.  Think of databases.  How do you guarantee that a record identifier is 100% unique and never used anywhere else?

A GUID, of course!

image

So, give your session variable names a GUID.  Each session variable gets a different GUID.  Don’t be so judgmental just yet.  Yes, of course, they’re impossible to remember and to type, but I’ll cover that in a moment.  For now, I’m solving the problem of accidental reuse.  You KNOW no one else is going to use the same GUID.  So, your SomeEventTime session variable now looks like this:

Session["E4D1DE1A-ECC9-45FF-8B78-C5CD16803CFF"]

Now, to solve THREE more problems at once… one of them that we just introduced:

Gaining intellisense, giving it a usable name, and giving it a type

Wrap your session variable up in a property.

 public DateTime SomeEventTime 
{
get{return (DateTime)Session["E4D1DE1A-ECC9-45FF-8B78-C5CD16803CFF"];}
set{Session["E4D1DE1A-ECC9-45FF-8B78-C5CD16803CFF"] = value;}
}

Now, when you use your session variable, you reference the property name.  This gives you intellisense, fully typed session variables, and eliminates any concern of the internal session variable name being too hard to remember and type out.

You’ve just gained another benefit by making it a property:  Triggers!

Now that it’s wrapped up in a property, you can add special code during the assignment or during the reading of the variable.

Scope

One last thing to consider:  Scope.

Where do you create the property wrapper?  In the page?  Do you make it private? Public?  Do you put it in Global.asax?  I’ll leave that up to you to judge on a per case bases.  It might be the topic of another article here too.

What have you done?

You’ve eliminated every problem you have with session variables and gained:

  1. Type Safety.
  2. Intellisense.
  3. Compile time name checking.
  4. Triggers on setting and reading.
  5. Scope.
  6. Prevention of accidental reuse of the same name.

You’ve lost:

  1. Embarrasing runtime bugs.
  2. Wasted time looking for hard to find logic problems caused by two different parts of the code using the same name for what was believed to be different session variables.

See this image?

image_thumb26

You’ll find an actual working version of it at the bottom of this article. Please click the appropriate buttons in it to let your friends know about this article.

Check back later for updates too!

Click here to follow me on Google+.

Leave a Reply