Use Generic Methods to create a Session Wrapper class

Getting values out of session in ASP.NET can be a bit of a pain for two reasons:

  1. You have to remember what you named the value when you put it in
  2. You have to type cast the value, as session stores it in an Object

One nice way to handle this is to build a wrapper class to handle getting values into and out of session. And an even nicer way is to use generic methods in your wrapper class.

Here’s how I implement this in my projects. First, I have a class called SessionBase that contains two shared Generic methods, LoadValue and RetrieveValue:

Public Class SessionBase

Public Shared Function RetrieveValue(Of T)(ByVal keyName As String) As T

If HttpContext.Current.Session(keyName) IsNot Nothing Then
Return DirectCast(HttpContext.Current.Session(keyName), T)
End If

End Function

Public Shared Sub LoadValue(Of T)(ByVal keyName As String, ByVal value As T)

HttpContext.Current.Session(keyName) = value

End Sub

End Class

The beauty of these methods is that they can handle any data type – I don’t have to have separate methods for integers, collections, custom types, etc. It’s all handled here in this generic and reusable class (I usually keep it in a .dll along with other base classes, and add a reference to it in my project). I use DirectCast rather than CType in my retrieve method because it is supposed to have less of a performance penalty.

Then, in my project, I create a class called sess that inherits the base class (because the base class contains shared methods, it doesn’t really need to be inherited, but I prefer to do it this way so there is less typing – I can type sess.LoadValue instead of TKS.SessionBase.LoadValue). In the project-specific class, I create constants for the session key names, and shared properties to load and retrieve values from session:

Public Class sess
Inherits TKS.Web.SessionBase

Private Const cProjID As String = "ProjID"
Private Const cProjName As String = "ProjName"

Public Shared Property ProjID() As Integer
Return sess.RetrieveValue(Of Integer)(cProjID)
End Get
Set(ByVal value As Integer)
sess.LoadValue(of Integer)(cProjID, value)
End Set
End Property

Public Shared Property ProjName() As String
Return sess.RetrieveValue(Of String)(cProjName)
End Get
Set(ByVal value As String)
sess.LoadValue(Of String)(cProjName, value)
End Set
End Property

End Class

Note how the generic methods are made specific at this point – Integer for ProjID, String for ProjName.

Now in my project, I can use the sess properties to easily access the session object:

Protected Sub btnLoad_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnLoad.Click

sess.ProjID = Integer.Parse(Me.txtProjectID.Text)
sess.ProjName = Me.txtProjectName.Text

End Sub

Protected Sub btnRetrieve_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRetrieve.Click

Me.txtProjectID.Text = sess.ProjID.ToString
Me.txtProjectName.Text = sess.ProjName

End Sub

Dynamically change Master Page body tag

Today I spent several hours butting up against this, and finally, after much gnashing of teeth, found this great blog entry explaining what I needed to know.

Basically, the problem is that I needed to call a javascript function onload in the body tag of the page, but of course in an ASP.NET Content page there is no body tag – it only occurs once in the Master Page. But I didn’t want to put my javascript call in the Master page body tag, because then it would be called on every page.

I tried putting it in window.onload in a script tag at the bottom of the page, but this then screwed up some ASP.NET-generated javascript from a validation control, and also some of my other javascript.

The solution put forth in the blog entry is to dynamically put the onload function call in the Master Pages body tag from code in the Content page. Don’t have time to show the code myself (it’s quittin’ time), but please feel free to follow the above link.

By the way, this still didn’t solve my problem in Mozilla, but it works in IE, and as this particular project is for a company intranet that only uses IE, I’m happy (at least for now).