ASP.NET overcomes all major limitations of ASP when it comes to managing session states. As you are aware from ASP development, a session state is nothing but a named variable that is cached at the server for the duration of the web user's session. As the user navigates through the web application, the session state retains its value as long as the session is not expired.
ASP session-state management can be summarized as follows:
The session starts, and the web application assigns a unique key to the user.
This key is stored in an HTTP cookie. Along each subsequent request, the client browser sends the unique key back to the server.
The server looks up the states stored for this particular key and processes the request accordingly.
Although this has worked fine for all these years, we've found out that there were a number of limitations to live with or work around. The biggest limitation is that the session state is process-dependent, which is impossible to implement in a web farm environment without custom session management.
ASP.NET improves on ASP session-state management by giving you the option to move to an out-of-process model. By having all web servers in the farm pointing to a common server that hosts the out-of-process state manager, the web client can be redirected around the farm without losing the session states.
By using an out-of-process model, we no longer have the problem of losing session states when the IIS process is cycled. This means that if the web server application crashed for whatever reason and restarted within the session timeout duration, the web clients could still have all their session states intact. Of course, if the out-of-process state manager crashed, that is a whole different issue. This leads to the next improvement of ASP.NETthe ability to persist session state to a database.
The idea of persisting session state to a database is not new. Many of us have implemented this as the workaround for dealing with web farm configuration. However, ASP.NET makes it easier.
Similar to all other configurations in ASP.NET, session management is done through the use of the web.config files. There are two levels of configuration: machine and application. Machine-level configuration associates with the machine.config file stored in WinNT\Microsoft.NET\ Framework\<version>\CONFIG\machine.config, while the application-level configuration uses the web.config file in the application root directory. The application-level configuration overrides the machine-level configuration.
The following code is a portion of the web.config file dealing with session-state management:[11]
[11] The content of this file is case-sensitive.
<configuration> <system.web> <sessionState mode="InProc" cookieless="false" timeout="20" /> </system.web> </configuration>
Table 7-2 lists the properties of the SessionState class.
Property |
Description |
---|---|
mode |
Off indicates that session state is disabled; InProc stores session data locally; StateServer stores session state on a remote server; and SQLServer stores it on a SQL Server. |
Cookieless |
Specifies whether to rely on the client acceptance of cookie. If this property is set to true, ASP.NET inserts the unique key to the URL for navigation between pages within the application instead of setting it in the client's cookie. |
Timeout |
Specifies session timeout in minutes. This is a sliding window of time: it starts counting down for each request. The default is 20 minutes. |
stateConnectionString |
Specifies the server and port of the remote session-state server (not a SQL Server). The format is tcpip=HOST:PORT, as in tcpip=192.168.254.1:42424. Use this only when mode=StateServer. |
sqlConnectionString |
Represents a SQL Server connection string, such as user id=sa;password=;database=ASPState;server=(local). This is required when mode=SQLServer. |
When you set the session-state mode to run on a remote server (mode=StateServer), you must prepare the remote server to run the state management service automatically.
ASP.NET SDK includes an NT service call ASP.NET State Service to be used for out-of-process session-state management. Before setting your web.config files to use the out-of-process mode, you will have to start the ASP State service by going to the NT Services Management Console and start the service. You might want to change the startup type to automatic so that this service will start automatically at subsequent reboots.
To use this mode, the SQL Server machine has to be prepared. ASP.NET SDK includes a SQL script to create the ASP State database, which is where all session states are stored. Find this SQL script (InstallSqlState.sql) at %SystemRoot%\Microsoft.NET\Framework\BUILDNUMBER\. To apply the script to your SQL Server, use the SQL Server command-line tool osql.exe or SQL Query Analyzer. We use the latter because it allows us to inspect the script to get a better understanding of how this mode of session management is implemented. You will have to stop and restart SQL Server because the script alters the master to run the ASPState_Startup helper procedure at SQL startup time.
In ASP development, it is a usual practice to impose the requirement that the clients' web browsers be set up to accept cookies so that we can use session state the way it is meant to be used. However, when this requirement is not in place, especially for business-to-consumer (B2C) kinds of applications, the developers have to package the session ID along with the URL as a variable in the query string or as a form field and manage the session states manually.
With ASP.NET, as you can see from the sessionstate section of the configuration file, all you do is flip the setting of cookieless to true, and everything is automatically done for you. Session state can be used as if nothing has changed.
To setup and experiment with these session-state configuration, we've created two fictitious asp.net pages: login.aspx and main.aspx. The main page redirects the user to the login page if the user has not logged in. The login page redirects the user to the main page when the user is authenticated. When the user logs in, session variable UserName will be populated.
The following is the source for the simplified login page:
<HTML> <script language="VB" runat="server"> Sub cmdLogin_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) ' more processing here Session("UserName") = txtUID.Text Response.Redirect("Main.aspx") End Sub </script> <body> <form id="Form1" method="post" runat="server"> <table> <tr> <td>User ID</td> <td><asp:TextBox id="txtUID" runat="server"></asp:TextBox></td> </tr> <tr> <td>Password</td> <td><asp:TextBox id="txtPWD" textmode="password" runat="server"> </asp:TextBox></td> </tr> <tr> <td></td> <td><asp:Button id="cmdLogin" runat="server" Text="Login" onclick="cmdLogin_Click"> </asp:Button></td> </tr> </table> </form> </body> </HTML>
The skeleton for the main page is as follows:
<HTML> <script language="VB" runat="server"> Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) If (Session("UserName") <> "") Then labelData.Text = "Welcome back, " + Session("UserName") Else Response.Redirect("Login.aspx") End If End Sub </script> <body> <form id="Form1" method="post" runat="server"> <asp:Label id="labelData" runat="server"></asp:Label> </form> </body> </HTML>
In the first scenario, we will use session-state mode InProc. Because the IIS process handles the session state, if we simulate a web server restart by issuing the command iisreset and trying to refresh the main page, it will redirect us to the login page.
In the second scenario, we change the session-state mode to StateServer and start the ASP.NET Session State Service (i.e., the command line net start aspnet_state). Note that here we are running the Session State Service on the same machine as the web server even though we can have this service running on a separate server for more reliability. This time around, the session state persists through the resetting of the web server. Of course, if we restart the ASP.NET Session State Service itself, the main page will still redirect us to the login page.
Now that we've seen in-process and out-of-process session-state management, the last scenario we try will be to have session state persisted to a database. This is as simple as setting the mode and the sqlConnectionString attributes of the sessionState node in the web.config file. Of course, we ran InstallSqlState.sql on the SQL server to generate theschema and supporting stored procedures needed by ASP.NET to persist state into the database. The result is similar to the previous trials, however. Because the session data are stored in tempdb, they are cleared when the SQL server is restarted. As a side note, remember to have SQL Server Agent start automatically so that the cleanup session-state job can be run correctly.
As we've said, ASP.NET introduces an out-of-process model of session-state management, which enables more scalable solutions, but not without a cost. Out-of-process communication performs much worse than in-process communication, not to mention persisting the session states to a database. You should weigh the benefits of each of the different modes of state managements to find the one that is most suitable for your application. Table 7-3 summarizes the different modes and their trade-offs.
Mode |
Description |
---|---|
In-process |
This mode gives you the best performance. It is not reliable, because it is memory-based. It is not scalable, because it is process-based. If you are setting up a web farm, you will have to make sure that subsequent requests are going to the same server. |
Out-of-process |
The reliability factor is still in question because this mode is still memory based. However, because a separate process manages the session state, it is more reliable than the in-process mode. Because of the out-of-process communication overhead, it is much slower than in-process mode. It is scalable for use in web farms. |
SQL Server |
This mode gives you the highest level of reliability at the cost of performance. It is scalable for use in web farms. |