One of the most common mistakes ASP.NET developers make is while accessing session variables. Have a look at the code below:
C#:
// Writing to session variable
Session["UserCountry"] = ddlUserCountry.SelectedValue;
// Reading from session variable
string userCountry = Session["UserCountry"].ToString();
VB:
' Writing to session variable
Session("UserCountry") = ddlUserCountry.SelectedValue
' Reading from session variable
Dim userCountry As String = Session("UserCountry").ToString()
I have seen such code across multiple aspx and ascx code behind pages and it is a disaster waiting to happen and has many drawbacks as follows:
1) If a session variable is read before it has been assigned or if the current session times out, it will result in NullReferenceException as no null checking happens before reading from session variable.
2) A simple spelling mistake of the key name used to identify the session variable ("UserCountry" in above example) will result in NullReferenceException (if no null checking is being done) or incorrect data (if null checking is being done).
3) In large ASP.NET projects where many developers are coding at the same time, very often two developers end up using the same key names for two different session variables meant for two different purposes. I have seen developers use the wildest key names for session variables like "Name" which is so common, it can be used by one developer to save the user's first name, and by another developer to save the user's user name. When such a situation arises, one of the session variable's key name would have to be changed across multiple aspx and ascx code behind pages, making sure that the other session variable sharing the same key name but meant for a different purpose is not changed by accident. This will result in complete chaos, and debugging and testing for such changes becomes a nightmare.
4) There is no easy way to track the usage of session variables, their key names, their data types, the approximate memory being used per session, etc.
However, with just a few extra lines of code and effort, we can get rid of above problems. To address above problems, we can create a single static / shared class (lets call it SessionHandler) which exposes all session variables through strongly typed static / shared properties. No aspx and ascx code behind pages should ever access session variables directly but instead access the strogly typed static / shared properties of the SessionHandler class. All the code to access session variables should exist ONLY in the SessionHandler class. Also, the SessionHandler class should use string variables to save key names of different session variables it exposes in order to avoid spelling mistakes. Have a look at the code below:
C#:
// Static / shared class for handling session variables
public static class SessionHandler
{
// Declare a string variable to hold the key name of the session variable
// and use this string variable instead of typing the key name
// in order to avoid spelling mistakes
private static string _userCountryKey = "UserCountry";
// Declare a static / shared strongly typed property to expose session variable
public static string UserCountry
{
get
{
// Check for null first
if (HttpContext.Current.Session[SessionHandler._userCountryKey] == null)
{
// Return an empty string if session variable is null
return string.Empty;
}
else
{
return HttpContext.Current.Session[SessionHandler._userCountryKey].ToString();
}
}
set
{
HttpContext.Current.Session[SessionHandler._userCountryKey] = value;
}
}
}
VB:
' Static / shared class for handling session variables
Public Class SessionHandler
' Declare a string variable to hold the key name of the session variable
' and use this string variable instead of typing the key name
' in order to avoid spelling mistakes
Private Shared _userCountryKey As String = "UserCountry"
' Declare a static / shared strongly typed property to expose session variable
Public Shared Property UserCountry() As String
Get
' Check for null first
If (HttpContext.Current.Session(SessionHandler._userCountryKey) Is Nothing) Then
' Return an empty string if session variable is null
Return String.Empty
Else
Return HttpContext.Current.Session(SessionHandler._userCountryKey).ToString()
End If
End Get
Set(ByVal value As String)
HttpContext.Current.Session(SessionHandler._userCountryKey) = value
End Set
End Property
End Class
Once we have the SessionHandler class in place, all aspx and ascx code behind pages can access session variables through this class like below. Notice that we dont access session variables directly anymore and let the SessionHandler class do all the required work to access session variables.
C#:
// Writing to session variable
SessionHandler.UserCountry = ddlCountry.SelectedValue;
// Reading from session variable
string userCountry = SessionHandler.UserCountry;
VB:
' Writing to session variable
SessionHandler.UserCountry = ddlUserCountry.SelectedValue
' Reading from session variable
Dim userCountry As String = SessionHandler.UserCountry
Now since all the code to access session variables exists in one single class, it becomes really easy to track their usage, their key names, their data types, the approximate memory being used per session, etc. Also notice how easy it would be to change the key name of a session variable if required. All you would have to do is change the value of one private static / shared variable ("_userCountryKey" in above example). Also, we can be 100% sure that we are not using duplicate key names for multiple session variables by simply checking the value of all existing private static / shared string variables being used to save key names by the SessionHandler class.
Note: We can use the same above architecture (with slight changes to code) to access data from ASP.NET Cache as well as Application Settings. I will blog about it in a future post.
Cheers,
Raj
~~~ CODING FOR ETERNITY !!! ~~~