Recipe 6.2 Maintaining Information about a User Throughout a Session

     

Recipe 6.2 Maintaining Information about a User Throughout a Session

6.2.1 Problem

You want to make personalized information available to the users of your application for as long as each remains active, without having to access a database each time the information is needed and regardless of the number of pages traversed.

6.2.2 Solution

Create a class in which to store the personalized data, instantiate the class and load the data, store the data object in the Session object, and then access the data from the Session object as required.

In the code-behind class for your ASP.NET pages that need access to the data, use the .NET language of your choice to:

  1. Check to see if the object used to store the personalized data exists in the Session object.

  2. If the object exists, retrieve the object from Session . If the object does not exist, instantiate the class used for the personalized data and store it in the Session object.

  3. Use the data as required in your application.

A simple example that illustrates this solution is shown in Examples Example 6-6 through Example 6-10. The example uses the class shown in Example 6-6 ( CH06PersonalDataVB for VB) and Example 6-7 ( CH06PersonalDataCS for C#) to provide a container for some simple personalization data. This class contains properties for each of the data items and a default constructor.

Figure 6-2 shows a simple form that we've created for viewing the current contents of the personalization data stored in the Session object and for entering new session state data values. Example 6-8 shows the .aspx file that produces the form. Example 6-9 and Example 6-10 show the companion VB and C# code-behind files.

Figure 6-2. Form for viewing and entering session state data values
figs/ancb_0602.gif

6.2.3 Discussion

The approach we favor for maintaining personal information about a user for the duration of a session ”an approach that is often referred to as personalization ”is to create a class to hold the data, instantiate and populate the object, store the object in the Session object, and then access the data from the Session object.

As its name implies, you can use the Session object in ASP.NET to store information needed for a particular user session. Variables stored in the Session object are not discarded when the user navigates between the pages of an application. Rather, they are persisted for the entire session.

To illustrate this approach, the code-behind in our example contains the logic needed to access the data in the Session object. We make use of the Page_Load method in Example 6-9 (VB) and Example 6-10 (C#) to first check whether the Session object contains the personalization data. If not, we create a new CH06PersonalDataVB (VB) or CH06PersonalDataCS (C#) object using default values, and store this new data object in the Session object associated with the current session. Otherwise, we retrieve a reference to the object containing the personalized data. Finally, we update the contents of the form by passing the personalization object to a method that uses the data to update the contents of the form.

In Example 6-9 and Example 6-10, a constant, SES_PERSONALIZATION_DATA , is used to define the name of the variable placed in the Session object. This is done to avoid having to hardcode the name of the variable in multiple locations in the code. In an application where the data is accessed in multiple pages, the constant should be stored in global.asax.vb (or global.asax.cs ) or in another class containing global constants.


For this example, the personalization data is updated when the user enters new personalization data values and clicks the Update button. In the button click event handler, we check whether the data has been stored in the Session object, using the same code we used in the Page_Load method. You should always check this condition to avoid the error that will be thrown if the data is no longer in the Session object. Loss of data can occur if the session times out and ASP.NET deletes all variables for the user session.

Next, we update the contents of the personalization object with data from the form. In a production setting, your code will need to perform validation on the data to ensure that it is of the correct type, in the correct form, within the correct range, and so on. Finally, we store the personalization data in the Session object and update the form contents.

This example is rather simple, but it shows the mechanics associated with storing and retrieving data in the Session object. In a full application, the personalization data could be read from a database when the user logs in. If your application uses cookies to identify a user, the Session_Start event handler of global.asax provides an ideal place to retrieve the cookie that identifies the user, get the user's personalization data from a database, and then place the data in the Session object.

You can place any object in the Session object, but take care not to overuse the Session object. Large objects can significantly impact the performance of the application by tying up system resources.

To provide the ability to associate session data with a specific user, ASP.NET assigns a session ID to each user session. The session ID is then used by ASP.NET to retrieve the Session object associated with the user requesting a page.

The HTTP protocol is stateless, so some method of associating the incoming requests with a specific user is required. By default, ASP.NET sends a cookie containing the session ID to the client browser as part of its response to the first page request by a user. Subsequent page requests return the cookie data. ASP.NET retrieves the cookie data from the request, extracts the session ID, retrieves the Session object for the specific user, and then processes the requested page.

The cookie sent to the client browser is an in-memory cookie and is not persisted on the client machine. If the user closes the browser, the cookie containing the session ID is destroyed .

To support applications that do not use cookies, ASP.NET provides the ability to automatically modify the URL to contain the session ID (called URL munging ). This method of tracking the session ID is configured in the web.config file and is discussed in Recipe 9.4.

ASP.NET supports three methods of storing the session information. By default, the session data is stored in memory within the ASP.NET process. The session data can also be stored in memory in an out-of-process state server or SQL Server. The storage methods are configured in the web.config file and are discussed in Recipe 9.4.

When using the Session object in your application, consider the following points:

  • By default, a session times out after 20 minutes of inactivity. When a session times out, the ASP.NET process destroys all session data, and the resources used by the session variables are recovered. The session timeout is configured in the web.config file and is discussed in Recipe 9.4.

  • If any special operations are required when a user session ends, they can be performed in the Session_End event handler of global.asax . This event is raised whenever a session ends, whether it is done programmatically or because the session times out. However, the Session_End event may not be raised if ASP.NET is terminated abruptly.

6.2.4 See Also

Recipe 9.4

Example 6-6. Class used to store data in session object (.vb)
 Option Explicit On  Option Strict On '----------------------------------------------------------------------------- ' '   Module Name: CH06PersonalDataVB.vb ' '   Description: This module provides the container to store personalization  '                data for a user ' '***************************************************************************** Namespace ASPNetCookbook.VBExamples   Public Class CH06PersonalDataVB     'private attributes with default values     Private mUsername As String = ""     Private mResultsPerPage As Integer = 25     Private mSortBy As String = "Title"     Public Property username( ) As String       Get         Return (mUsername)       End Get       Set(ByVal Value As String)         mUsername = Value       End Set     End Property  'username     Public Property resultsPerPage( ) As Integer       Get         Return (mResultsPerPage)       End Get       Set(ByVal Value As Integer)         mResultsPerPage = Value       End Set     End Property  'resultsPerPage     Public Property sortBy( ) As String       Get         Return (mSortBy)       End Get       Set(ByVal Value As String)         mSortBy = Value       End Set     End Property  'sortBy   End Class  'CH06PersonalDataVB End Namespace 

Example 6-7. Class used to store data in session object (.cs)
 //---------------------------------------------------------------------------- // //   Module Name: CH06PersonalDataCS // //   Description: This module provides the container to store personalization  //                data for a user // //**************************************************************************** using System; namespace ASPNetCookbook.CSExamples {   public class CH06PersonalDataCS   {     // private attributes with default values     private String mUsername = "";     private int mResultsPerPage = 25;     private String mSortBy = "Title";     public String username     {       get       {         return(mUsername);       }       set       {         mUsername = value;       }     }  // username     public int resultsPerPage     {       get       {         return(mResultsPerPage);       }       set       {         mResultsPerPage = value;       }     }  // resultsPerPage     public String sortBy     {       get       {         return(mSortBy);       }       set       {         mSortBy = value;       }     }  // mSortBy   }  // CH06PersonalDataCS } 

Example 6-8. Maintaining user state (.aspx)
 <%@ Page Language="vb" AutoEventWireup="false"           Codebehind="CH06SessionStateVB.aspx.vb"           Inherits="ASPNetCookbook.VBExamples.CH06SessionStateVB" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html>   <head>     <title>State Session</title>     <link rel="stylesheet" href="css/ASPNetCookbook.css">   </head>   <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0">     <form id="frmSessionState" method="post" runat="server">       <table width="100%" cellpadding="0" cellspacing="0" border="0">         <tr>           <td align="center">             <img src="images/ASPNETCookbookHeading_blue.gif">           </td>         </tr>         <tr>           <td class="dividerLine">             <img src="images/spacer.gif" height="6" border="0"></td>         </tr>       </table>       <table width="90%" align="center" border="0">         <tr>           <td><img src="images/spacer.gif" height="10" border="0"></td>         </tr>         <tr>           <td align="center" class="PageHeading">             Maintaining Session State (VB)           </td>         </tr>         <tr>           <td><img src="images/spacer.gif" height="10" border="0"></td>         </tr>         <tr>           <td align="center">             <table width="60%" align="center">               <tr>                 <td colspan="2" align="center" class="PageHeading">                   Current Session Data Values</td>               </tr>               <tr class="MenuItem">                 <td>User Name: </td>                 <td><asp:Label ID="labUserName" Runat="server" /></td>               </tr>               <tr class="MenuItem">                 <td>Results Per Page: </td>                 <td><asp:Label ID="labResultsPerPage" Runat="server" /></td>               </tr>               <tr class="MenuItem">                 <td>Sort By: </td>                 <td><asp:Label ID="labSortBy" Runat="server" /></td>               </tr>             </table>             <br />             <table width="60%" align="center">               <tr>                 <td colspan="2" align="center" class="PageHeading">                   Enter New Session Data Values</td>               </tr>               <tr class="MenuItem">                 <td>User Name: </td>                 <td><asp:TextBox ID="txtUserName" Runat="server" /></td>               </tr>               <tr class="MenuItem">                 <td>Results Per Page: </td>                 <td><asp:TextBox ID="txtResultsPerPage" Runat="server" /></td>               </tr>               <tr class="MenuItem">                 <td>Sort By: </td>                 <td><asp:TextBox ID="txtSortBy" Runat="server" /></td>               </tr>               <tr>                 <td colspan="2" align="center">                   <br />                   <asp:ImageButton ID="btnUpdate" Runat="server"                         ImageUrl="images/buttons/button_update.gif" />                 </td>               </tr>             </table>           </td>         </tr>       </table>     </form>   </body> </html> 

Example 6-9. Maintaining user state (.vb)
 Option Explicit On  Option Strict On '----------------------------------------------------------------------------- ' '   Module Name: CH06SessionStateVB.aspx.vb ' '   Description: This module provides the code behind for '                CH06SessionStateVB.aspx ' '***************************************************************************** Imports Microsoft.VisualBasic Namespace ASPNetCookbook.VBExamples   Public Class CH06SessionStateVB     Inherits System.Web.UI.Page     'controls on the form     Protected labUserName As System.Web.UI.WebControls.Label     Protected labResultsPerPage As System.Web.UI.WebControls.Label     Protected labSortBy As System.Web.UI.WebControls.Label     Protected txtUserName As System.Web.UI.WebControls.TextBox     Protected txtResultsPerPage As System.Web.UI.WebControls.TextBox     Protected txtSortBy As System.Web.UI.WebControls.TextBox     Protected WithEvents btnUpdate As System.Web.UI.WebControls.ImageButton  'The following constant defines the name of the session variable used   'to store the user personalization data   Public SES_PERSONALIZATION_DATA As String = "PersonalizationData"  '*************************************************************************     '     '   ROUTINE: Page_Load     '     '   DESCRIPTION: This routine provides the event handler for the page load     '                event.  It is responsible for initializing the controls      '                on the page.     '-------------------------------------------------------------------------     Private Sub Page_Load(ByVal sender As System.Object, _                           ByVal e As System.EventArgs) Handles MyBase.Load  Dim personalData As CH06PersonalDataVB   If (Not Page.IsPostBack( )) Then   'check to see if the session data exists   If (IsNothing(Session(SES_PERSONALIZATION_DATA))) Then   'data does not exist in session so create a new personalization   'object and place it in session scope   personalData = New CH06PersonalDataVB   Session.Add(SES_PERSONALIZATION_DATA, _   personalData)   Else   'data exists in session so get a reference to the data   personalData = CType(Session(SES_PERSONALIZATION_DATA), _   CH06PersonalDataVB)   End If   'update contents on the form   updateFormData(personalData)   End If  End Sub  'Page_Load     '*************************************************************************     '     '   ROUTINE: btnUpdate_Click     '     '   DESCRIPTION: This routine provides the event handler for the update     '                button click event.  It is responsible for updating the     '                contents of the session variable used to store the      '                personalization data and updating the form.     '-------------------------------------------------------------------------  Private Sub btnUpdate_Click(ByVal sender As Object, _   ByVal e As System.Web.UI.ImageClickEventArgs) _   Handles btnUpdate.Click   Dim personalData As CH06PersonalDataVB   'check to see if the session data exists   If (IsNothing(Session(SES_PERSONALIZATION_DATA))) Then   'data does not exist in session so create a new personalization object   personalData = New CH06PersonalDataVB   Else   'data exists in session so get a reference to the data   personalData = CType(Session(SES_PERSONALIZATION_DATA), _   CH06PersonalDataVB)   End If   'update contents of session object from form   personalData.username = txtUserName.Text   personalData.resultsPerPage = CInt(txtResultsPerPage.Text)   personalData.sortBy = txtSortBy.Text   'update contents of session object   Session(SES_PERSONALIZATION_DATA) = personalData   'update contents on the form   updateFormData(personalData)   End Sub  'btnUpdate_Click  '*************************************************************************     '     '   ROUTINE: updateFormData     '     '   DESCRIPTION: This routine updates the contents of the form from the     '                passed data.     '-------------------------------------------------------------------------     Private Sub updateFormData(ByVal personalData As CH06PersonalDataVB)       labUserName.Text = personalData.username       labResultsPerPage.Text = personalData.resultsPerPage.ToString( )       labSortBy.Text = personalData.sortBy     End Sub  'updateFormData   End Class  'CH06SessionStateVB End Namespace 

Example 6-10. Maintaining user state (.cs)
 //---------------------------------------------------------------------------- // //   Module Name: CH06SessionStateCS.ascx.cs // //   Description: This module provides the code behind for //                CH06SessionStateCS.ascx // //**************************************************************************** using System; using System.Web.UI; using System.Web.UI.WebControls; namespace ASPNetCookbook.CSExamples {   public class CH06SessionStateCS : System.Web.UI.Page   {     // controls on the form     protected System.Web.UI.WebControls.Label labUserName;     protected System.Web.UI.WebControls.Label labResultsPerPage;     protected System.Web.UI.WebControls.Label labSortBy;     protected System.Web.UI.WebControls.TextBox txtUserName;     protected System.Web.UI.WebControls.TextBox txtResultsPerPage;     protected System.Web.UI.WebControls.TextBox txtSortBy;     protected System.Web.UI.WebControls.ImageButton btnUpdate;  // The following constant defines the name of the session variable used   // to store the user personalization data   public String SES_PERSONALIZATION_DATA = "PersonalizationData";  //************************************************************************     //     //   ROUTINE: Page_Load     //     //   DESCRIPTION: This routine provides the event handler for the page      //                load event.  It is responsible for initializing the      //                controls on the page.     //------------------------------------------------------------------------     private void Page_Load(object sender, System.EventArgs e)     {  CH06PersonalDataCS personalData = null;   // wire the update button click event   this.btnUpdate.Click +=   new ImageClickEventHandler(this.btnUpdate_Click);   if (!Page.IsPostBack)   {   // check to see if the session data exists   if (Session[SES_PERSONALIZATION_DATA] == null)   {   // data does not exist in session so create a new personalization   // object and place it in session scope   personalData = new CH06PersonalDataCS( );   Session.Add(SES_PERSONALIZATION_DATA,   personalData);   }   else   {   // data exists in session so get a reference to the data   personalData = (CH06PersonalDataCS)   (Session[SES_PERSONALIZATION_DATA]);   }   // update contents on the form   updateFormData(personalData);   }  }  // Page_Load     //************************************************************************     //     //   ROUTINE: btnUpdate_Click     //     //   DESCRIPTION: This routine provides the event handler for the update     //                button click event.  It is responsible for updating the     //                contents of the session variable used to store the      //                personalization data and updating the form.     //------------------------------------------------------------------------  private void btnUpdate_Click(Object sender,   System.Web.UI.ImageClickEventArgs e)   {   CH06PersonalDataCS personalData = null;     //check to see if the session data exists   if (Session[SES_PERSONALIZATION_DATA] == null)   {   // data does not exist in session so create a new   // personalization object   personalData = new CH06PersonalDataCS( );   }   else   {   //data exists in session so get a reference to the data   personalData = (CH06PersonalDataCS)(Session[SES_PERSONALIZATION_DATA]);   }   // update contents of session object from form   personalData.username = txtUserName.Text;   personalData.resultsPerPage = Convert.ToInt32(txtResultsPerPage.Text);   personalData.sortBy = txtSortBy.Text;   //update contents of session object   Session[SES_PERSONALIZATION_DATA] = personalData;   // update contents on the form   updateFormData(personalData);   }  // btnUpdate_Click  //************************************************************************     //     //   ROUTINE: updateFormData     //     //   DESCRIPTION: This routine updates the contents of the form from the     //                passed data.     //------------------------------------------------------------------------     private void updateFormData(CH06PersonalDataCS personalData)     {       labUserName.Text = personalData.username;       labResultsPerPage.Text = personalData.resultsPerPage.ToString( );       labSortBy.Text = personalData.sortBy;     }  // updateFormData   }  // CH06SessionStateCS } 



ASP. NET Cookbook
ASP.Net 2.0 Cookbook (Cookbooks (OReilly))
ISBN: 0596100647
EAN: 2147483647
Year: 2006
Pages: 179

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net