Session Primer

Session and state management is a lot better in ASP.Net that it was in older technologies. However, there are still a number of hoops to jump through with each application that we wanted abstracted so we can change the implementation in the future if needed.

Specific questions we need to be able to answer or capabilities we need to support:

  1. Is the user logged in and when did the login occur?
  2. Historically, what pages are getting used?
  3. Ability to shift from ASP.Net in-memory sessions to database sessions

Let’s start with 1 and 2.

Almost every page in a user-authenticated web-application needs to answer question number 1. If the user is not logged in, or the login occurred too long ago, the user needs to be taken somewhere to log in.

A UserId or something simple can be stored in a cookie but that’s easy to spoof. A UserId could be stored in the session but you’ll need to find another solution if the client doesn’t want the user to have to log in every time the session expires and you don’t want stuff held in memory for too long.

The approach we take today is the same approach we were taking 10 years ago. Create a Session table (AppSession) in the database that is archived regularly to keep it small. Store the SessionId in the user’s cookie and when a page is requested, get the SessionId and the IPAddress and compare it with active sessions in the database. If the session is found, return it. If no session is found, create a new session. In scenarios where new sessions are created, no user is known so if the page requires authentication, other layers in the application will route the user to the correct page.

The majority of this logic can be found in the class App_Code/Domain/AppSession.vb and in the stored procedure ncAppSession_Get.

To answers questions similar to number 2, we also pass the requested page’s url to the database when we request the session. The stored procedure adds the SessionId and URL to the AppSessionActivity table creating a log of pages used by session, and when a user is logged in, by user by session. This allows us to create very detailed reports of user activity.

Issue number 3 is handled by using wrapper functions found in UnfiedASP.System.Utility.vb class. In many cases, we use the native in-memory session collections provided by .Net.


Shared Function GetSessionValue(ByVal key As String) As Object

	Try
		Return HttpContext.Current.Session(key)
	Catch ex As Exception
		Return Nothing
	End Try

End Function

Shared Sub SetSessionValue(ByVal key As String, ByVal value As Object)

	Try
		HttpContext.Current.Session(key) = value
	Catch ex As Exception

	End Try
End Sub

When a page or business object needs to set or get a session value, it uses these methods instead of interacting with the session object directly.

In situations where in-memory session does not work or meet requirements, we shift to data-driven sessions keyed off the AppSession object used for user authentication/authorization. We then change the implementation for the objects to what is shown below.


Shared Function GetSessionValue(ByVal key As String) As Object

	Try
		Dim appSessionId As Integer = Convert.ToInt32(HttpContext.Current.Request.Cookies("xid").Value)
		Dim sessionValue As New UnifiedASP.Domain.AppSessionValue
		sessionValue.AppSessionId = appSessionId
		sessionValue.ItemKey = key
		sessionValue.LoadForItemKey()
		Return sessionValue.ItemValue
	Catch ex As Exception
		Return Nothing
	End Try

End Function

Shared Sub SetSessionValue(ByVal key As String, ByVal value As Object)

	Try
		Dim appSessionId As Integer = Convert.ToInt32(HttpContext.Current.Request.Cookies("xid").Value)
		Dim sessionValue As New UnifiedASP.Domain.AppSessionValue
		sessionValue.AppSessionId = appSessionId
		sessionValue.ItemKey = key
		sessionValue.ItemValue = value
		sessionValue.Save()
	Catch ex As Exception

	End Try

End Sub
Share It:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • E-mail this story to a friend!
  • Netvibes
  • Ping.fm
  • Reddit
  • StumbleUpon
  • Technorati