Custom Sessions or Defining Global Objects in ASP.Net

One of the policies I've adopted as a developer swimming amidst a plethora of available technologies and libraries is, if I can write my own stable implementation in a reasonable amount of time I should do it. I've found that if I rely just a little too much on built in libraries or 3rd party solutions the reliability and scalability of my implementations is too far out of my control. Such has been my experience with Session management in classic ASP and ASP.Net.

While many of the restrictions that were present in classic ASP Session management have been resolved in ASP.Net communication between the two is still one advantage a custom system has over both native implementations. In fact, a custom session management system can be used to tie PHP, Perl, ColdFusion or any gateway language that is capable of connecting to a common database together.

Still, as a classic ASP developer for nearly 8 years it wasn't immediately obvious how to implement something like this on ASP.Net. In classic ASP it was simply a matter of defining an object of a custom class type and having it call a method which would take the session ID as an argument. This allowed the session ID to be stored in a cookie or, for cookieless implementations, the querystring.

Dim mySession
Set mySession = New CustomSession
mySession.Load(Request.QueryString("sessionid"))

Even simpler, this code could be stored in an include file so this was easily implemented on every page of a website in a single line. From there any page could access session information in nearly the exact same fashion as the built in Session collection.

Dim loginid
' Store a value
mySession.Value("username") = "sruport"
' Read a value
loginid = mySession.Value("loginid")

Other developers making the switch from ASP to ASP.Net may be tempted to use the ASP.Net user control to replace include functionality as I did. However this method is confusing, cumbersome and obviously not intended for such use. Another thing you might be tempted to try is to create a static (shared for you VB.Net programmers) global object. Don't do it. Static objects are application wide which means that if two or more people are logged in their session information will be constantly overwritten by one another.

One option is to toss the Session object into the Context collection of the HttpRequest object. While this works it's still not quite as elegant as you might hope. Really the question becomes how do you create a globally accessible variable for each request? The answer is to simply create a custom class that inherits the ASP.Net Page control. From there you can either add some additional members and code to manage your sessions or override the Session object entirely.

//C# Code
public class Page : System.Web.UI.Page
{

   private CustomSession _session;
   public new CustomSession Session { get { return _session; } }

   public Page() { this.Load += new EventHandler(Page_Load); }

   void Page_Load(object sender, EventArgs e)
   {
      _session = new CustomSession(Request);
   }

}

Or in VB.Net

'VB Code
Public Class Page : Inherits System.Web.UI.Page
   Private _Session As CustomSession

   Public Shadows ReadOnly Property Session() As CustomSession
      Get
         Return _Session
      End Get
   End Property

   Private Sub Page_Load(ByVal sender As Object, _
      ByVal e As System.EventArgs) Handles MyBase.Load
      _Session = New CustomSession(Request)
   End Sub
End Class

Then all you need to do is change the code behinds on all your ASPX pages to inherit this class instead of the System.Web.UI.Page class.

The last step is to create a custom session class to fit your needs. Personally, my constructor simply takes the Request parameter and grabs the SessionID from the querystring uses that to gather the session information record from the database. Session variables and values are stored in the database using a simple comma separated encoding. Creating my own session collection is just a matter of splitting and concatenating values to and from the database. Just remember if you're using a cookieless implementation you'll need to change each link to forward the SessionID in the querystring otherwise your users will suddenly lose their sessions. I may give a more in depth example if enough people are interested.

Whether you're trying to create your own custom session management or just trying to figure out how to properly define a "Global" object in ASP.Net I hope this article helped out.