devtutor: Working With the Session in ASP.NET

The Session in ASP.NET

ASP.NET, like its predecessor, provides a utility for maintaining state for visitors to your web application: the Session object.  The .NET version of the Session object has been greatly improved from its former version in ASP.  First off, the Session can now exist for browsers that have cookies disabled by using query string based session keys.  Furthermore, Sessions can be stored to a database allowing them to function in server farm environments (granted, a bit beyond the scope of departmental/organization developed applications).  Finally, as all objects in the .NET environment are now marsheled as XML structured data, the Session can hold true objects (rather than just straight data).

These advances in the Session object, coupled with some very powerful classes in the .NET framework, allow for a powerful and easy to use/code state management object.  This tutorial is designed to present you with a set of guidelines for when and how to best make use of the Session object.

When (and What) the Session Should be Used

The Session object is intended to be used to maintain state for a given visitor to your application.  As such, it should maintain information and provide functions/methods specific to the visitor.  It is **not** the appropriate storage object to contain resources available to all of the users of your application (i.e. database objects, site settings, etc.).  The Application object is a much more appropriate container for such resources.

Care must be taken when planning the life cycle of a user's Session object.  A Session should come into existence when a user arrives at the start of a self-contained process of your application and should be removed by either a predetermined timeout (the default is 20 minutes) or when the user completes the self-contained process (so, if the user wants to repeat the process with different information, they won't run into any unexpected issues caused by their previous pass through).

Planning a Session

Let's say my application is a simple two page form that will send an email:

Application Example - Pages:

 
   

Page 1 - Contact Information:

 

   
   Name:  
   Email Address:  
     
 

 

 
   

Page 2 - Feedback:

 

   
   Feedback:  
     
 

Given this design, my Session should probably be designed as an object with three exposed string properties (Name, Email, Feedback) and one method (SendFeedback).  In the event that any of the properites are empty, the SendFeedback method with throw an exception.  The code for such a Session class would look like this:

using System;
using System.Web.Mail;

namespace feedbackForm
{
public class SessionFeedback
{
private string m_sName;
private string m_sEmail;
private string m_sFeedback;

public string Name
{
get { return m_sName; }
set { m_sName = value ; }
}
public string Email
{
get { return m_sEmail; }
set { m_sEmail = value ; }
}
public string Feedback
{
get { return m_sFeedback; }
set { m_sFeedback = value ; }
}

public void SendFeedback()
{
/*
The call of the SmtpMail.Send method makes use of an Application object to get the feedback recipient's email address, the feedback subject, and the template of the email message.  The Replace method is used to insert the submitter's name and feedback into the template.  Details on how to create such an Application object can be found in the Application Object tutorial.
*/


if (m_sName.Length == 0)
throw new ApplicationException("Missing name.");
if (m_sEmail.Length == 0)
throw new ApplicationException("Missing email.");
if (m_sFeedback.Length == 0)
throw new ApplicationException("Missing feedback.");
SmtpMail.Send(
m_sEmail,
ApplicationFeedback.Current.FeedbackRecipient,
ApplicationFeedback.Current.Subject,
ApplicationFeedback.Current.BodyTemplate.Replace("<name/>", m_sName).Replace("<feedback/>", m_sFeedback)
);
}
}
}

Accessing the Session

Like the older ASP Session model, the SessionState utility is a keyword indexed collection.  But, as I stated earlier, since the new SessionState can store objects, there is a much easier way to access your custom Session without knowing the keywork for the collection index.  This technique is accomplished by making use of the "Current" property of the System.Web.HttpContext class (which allows objects outside of the web page to access the web page's context.

To access the Session, a static property on the Session is used to reference the current Session or, if it doesn't exist, to create it.  Please note the two additions to the Session class; the private constructor and the public, static Current property.  In order to support these additions, two library references have been added as well as a supporting private variables.  Finally, just before the SendFeedback method completes, the Session is removed.

using System;
using System.Web.Mail;
/* Added library references. */
using System.Web;
using System.Web.SessionState;

namespace feedbackForm
{
public class SessionFeedback
{
/* Web SessionState private variable. */
private HttpSessionState m_webSession;
private string m_sName;
private string m_sEmail;
private string m_sFeedback;

/* Private Constructor */
private SessionFeedback(HttpSessionState Session)
{
m_webSession = Session;
m_sName = "";
m_sEmail = "";
m_sFeedback = "";
}
public string Name
{
get { return m_sName; }
set { m_sName = value ; }
}
public string Email
{
get { return m_sEmail; }
set { m_sEmail = value ; }
}
public string Feedback
{
get { return m_sFeedback; }
set { m_sFeedback = value ; }
}
/* Public, static "Current" property */
public static SessionFeedback Current
{
HttpSessionState webSession = HttpContext.Current.Session;
SessionFeedback mySession = null;
mySession = ((SessionFeedback)(webSession["SessionFeedbackKey"]);

if (mySession == null)
{
mySession = new SessionFeedback(webSession);
webSession.Add("SessionFeedbackKey", mySession);
}

return mySession;
}

public void SendFeedback()
{
if (m_sName.Length == 0)
throw new ApplicationException("Missing name.");
if (m_sEmail.Length == 0)
throw new ApplicationException("Missing email.");
if (m_sFeedback.Length == 0)
throw new ApplicationException("Missing feedback.");
SmtpMail.Send(
m_sEmail,
ApplicationFeedback.Current.FeedbackRecipient,
ApplicationFeedback.Current.Subject,
ApplicationFeedback.Current.BodyTemplate.Replace("<name/>", m_sName).Replace("<feedback/>", m_sFeedback)
);

/* Removing the Session */
m_webSession.Remove("SessionFeedbackKey");
}
}
}

Conclusion

With this custom Session class now defined, the ASPX pages in the site will be able to access both the data and the email functionality for a user by using the static "Current" property.  Additionally, the location within the HttpSessionState collection and the life span of the Session is completely managed from within the object.  This greatly simplifies the code that is needed in the ASPX page itself.  Please email any comments regarding this tutorial to Will Hilley at whilley@ase.tufts.edu.  Enjoy!!!


Web Services
 ITSearch   Go
  © 2008 Tufts University. All rights reserved.