A Free Trial That Lets You Build Big!
Start building with 50+ products and up to 12 months usage for Elastic Compute Service
In a stateless environment such as a web application, understanding the concept of session state has no practical significance. However, effective State management is a required feature for most web applications. Microsoft ASP. NET and many other server-side programming environments provide an abstraction layer that allows applications to store persistent data based on each user and each application.
Note that the session Status of a Web application is the data cached and retrieved by the application in different requests. A session indicates all requests sent by the user during connection with the site. The session status is a collection of persistent data that the user generates and uses during the session. The status of each session is independent from each other and does not exist at the end of the user session.
The session status does not correspond to any logical entity that constitutes the HTTP protocol and specifications. A session is an abstract layer built by a server development environment (such as traditional ASP and ASP. NET. The way ASP. Net displays the session Status and the internal implementation of the session status depend on the basic structure of the platform. Therefore, the traditional ASP and ASP. NET achieve the session state in a completely different way. It is expected that the next version of ASP. NET will be further improved and enhanced.
This article discusses how to implement session state in ASP. NET 1.1 and how to optimize session state management in Managed Web applications.
ASP. NET session status overview
The session status is not part of the HTTP infrastructure. That is to say, there should be a structure component that binds the session status with each incoming request. The runtime environment (traditional ASP or ASP. NET) can accept keywords such as session and use it to indicate data blocks stored on the server. To successfully parse the call of the session object, the runtime environment must add the session status to the call context of the request being processed. This operation varies by platform, but it is a basic operation for stateful Web applications.
In traditional ASP, session states are implemented as ASP. dll libraries that contain free-threaded COM objects. (Are you curious about this? In fact, the CLSID of this object is the D97A6DA0-A865-11cf-83AF-00A0C90C2BD8 .) This object stores data organized by name/value pairs. The "name" Placeholder represents the keyword used to retrieve information, and the "value" Placeholder represents the content stored in the session state. Name/value pairs are grouped by session ID. In this way, each user can see only the name/value pairs he/she has created.
In ASP. NET, session State programming interfaces are almost the same as traditional ASP interfaces. However, their basic implementations are completely different. The former has more flexibility, scalability, and stronger programming functions than the latter. Before studying ASP. NET session Status, let's briefly review some structure functions of ASP. NET session infrastructure.
In ASP. NET, any incoming HTTP request must be transmitted through the HTTP module pipeline. Each module can filter and modify a large amount of information carried by the request. The information associated with each request is called "call context", which is expressed by the httpcontext object in programming. We should not regard the request context as another container of status information, although the items set provided by it is only a data container. The httpcontext object is different from all other State objects (such as Session, application, and cache) because its limited lifecycle exceeds the time required to process the request. After a request passes a series of registered HTTP modules, its httpcontext object will contain reference of the status object. When the request can be processed, the associated call context is bound to a specific session and global state object (Application and cache ).
The HTTP module that sets the session status for each user is sessionstatemodule. The structure of this module is designed according to the ihttpmodule interface, which provides a large number of services related to session status for ASP. NET applications. This includes generating session IDs, cookieless session management, retrieving session data from external State providers, and binding data to the request's call context.
The HTTP module does not store session data internally. The session status is always stored in an external component named "status provider. The status provider completely encapsulates session status data and communicates with other parts through the istateclientmanager interface. The HTTP module calls the method on this interface to read and save the session status. ASP. NET 1.1 supports three different state providers, as shown in table 1.
Table 1: Status client provider
Inproc session Value? Windows server? The memory of aspnet_wp.exe or w3wp.exe in 2003 is kept as the active object. This is the default option.
StateServer session values are serialized and stored in the memory of a separate process (aspnet_state.exe. This process can also run on other computers.
SQL Server session values are serialized and stored in Microsoft? SQL Server? Table. SQL Server instances can be run locally or remotely.
The session Status HTTP module reads the selected status provider from the <sessionstate> section of the web. config file.
<Sessionstate mode = "inproc | StateServer | sqlserver/>;
Based on the value of the mode feature, sessions are retrieved from different processes through different steps and stored in different processes. By default, session status is stored in the local ASP. NET auxiliary process. In special cases, it is stored in the special slot of the ASP. NET cache object (cannot be accessed through programming ). The session status can also be stored outside or even in remote processes (for example, in the Windows NT service named aspnet_state.exe ). The third option is to store the session status in a dedicated database table managed by SQL Server 2000.
The HTTP module deserializes session values at the beginning of the request to make them dictionary objects. Then, the attribute sessions displayed by the classes (such as httpcontext and page) are programmed to access the dictionary (actually an object of the httpsessionstate type ). The binding between the session status value and the visible Session Object of the developer continues until the end of the request. If the request is successfully completed, all status values will be serialized back to the status provider and can be used for other requests.
Figure 1 illustrates the communication between the requested ASP. NET page and the session value. The code used on each page is related to the session attribute on the page class. The programming method is almost the same as that of traditional ASP.
Figure 1: session Status architecture in ASP. NET 1.1
The physical value of the session status is locked within the time required to complete the request. The lock is managed internally by the HTTP module and used to synchronize Access to the session status.
The session Status Module instantiates the application status provider and initializes the application using the information read from the Web. config file. Next, each provider will continue its own initialization operations. The initialization operations vary depending on the type of the provider. For example, the SQL Server Status manager opens a connection to a given database, and the out-of-Process Manager checks the specified TCP port. On the other hand, inproc status Manager stores references to callback functions. This operation is performed when an element is deleted from the cache and is used to trigger the session_onend event of the application.
Synchronous Access session Status
What happens when the web page calls the session attribute very easily and intuitively? Many operations are performed in the background, as shown in the following tedious code:
Int sitecount = convert. toint32 (session ["counter"]);
The above Code actually accesses a copy of the session value created by the HTTP module in the local memory and reads data from a specific status provider (see figure 1. What if other pages attempt to access the session Status synchronously? In this case, the current request may stop Processing Inconsistent data or outdated data. To avoid this situation, the session Status Module locks the reader/writer and queues access to the Status values. Pages with write permission on the session status will keep the writer lock for the session until the request is terminated.
By setting the enablesessionstate attribute of the @ page command to true, the page can request the write permission for the session status. (This is the default setting ). However, the page can also have read-only permissions for session status. For example, when the enablesessionstate attribute is set to readonly. In this case, the module will lock the reader of the session until the request on the page ends. The result is read concurrently.
If a reader is locked for a page request, other requests simultaneously processed in the same session cannot update the session status, but can at least be read. That is to say, if a read-only request is being processed, the waiting read-only request has a higher priority than the request requiring full access. If a page request sets a writer lock for the session status, all other pages will be blocked, whether or not they want to read or write content. For example, if two frameworks attempt to write content in the session, one framework must wait until the other framework completes.
Comparison status provider
By default, ASP. NET applications store session states in the memory of the secondary process, especially in the dedicated slot of the cache object. When inproc mode is selected, the session status is stored in the slot of the cache object. This slot is marked as a dedicated slot and cannot be accessed by programming. In other words, if you enumerate all items in the ASP. NET data cache, no objects similar to the given session state will be returned. Cache objects provide two types of slots: Private slots and public slots. Programmers can add and process public slots, but specialized slots can only be used by systems (especially classes defined in system. Web components.
The status of each active session occupies a dedicated slot in the cache. The slot name is based on the session ID. Its value is an instance of the class not declared in sessionstateitem. The inproc status provider obtains the session ID and retrieves the corresponding elements in the cache. Then, the content of the sessionstateitem object is input into the httpsessionstate dictionary object and accessed by the application through the session attribute. Note that an error exists in ASP. NET 1.0, so that the dedicated slot of the cache object can be enumerated by programming. If you run the following code in ASP. NET 1.0, You can enumerate the items that correspond to the objects in the current active session status.
Foreach (dictionaryentry ELEM in cache)
Response. Write (ELEM. Key + ":" + ELEM. value. tostring ());
This error has been fixed in ASP. NET 1.1. When you enumerate cached content, no system slots are listed.
So far, inproc may be the fastest access option. But remember, the more data stored in sessions, the more memory the Web server consumes, which may increase the risk of performance reduction. If you plan to use any out-of-Process Solutions, consider the possible impact of serialization and deserialization. The out-of-process solution uses the Windows NT Service (aspnet_state.exe) or SQL Server table to store session values. Therefore, the session state is retained outside the ASP. NET auxiliary process, and an additional code layer is required for serialization and deserialization between the session state and the actual storage media. This operation occurs as long as the request is processed and must be optimized to the maximum extent subsequently.
Because the session data needs to be copied from the external repository to the local session dictionary, the request performance is reduced by 15% (out-of-process) to 25% (SQL Server ). Please note that although this is only a rough estimate, it should be close to the minimum impact, and the maximum impact will be much higher than this. In fact, this estimation does not fully consider the complexity of the type actually saved in the session state.
In the out-of-process storage solution, the session status remains longer, making the application more powerful, because it can prevent Microsoft? Internet Information Service (IIS) and ASP. NET fail. By separating session states from applications, you can also easily extend existing applications to the Web farm and web garden architectures. In addition, session states are stored in external processes, which fundamentally eliminates the risk of periodic data loss caused by process loops.
The following describes how to use the Windows NT Service. As mentioned above, the NT Service is a process named aspnet_state.exe, usually located in the C: \ winnt \ Microsoft. NET \ framework \ v1.1.4322 folder.
The actual directory depends on the Microsoft? . NET Framework version. Before using a status server, ensure that the service is ready and running on a local or remote computer used as a session storage device. Status service is an integral part of ASP. NET and is installed with it. Therefore, you do not need to run other installers. By default, the status service is not running and needs to be started manually. The ASP. NET application immediately tries to establish a connection with the server after it is loaded. Therefore, the service must be ready and running; otherwise, an HTTP exception is thrown. The Service Properties dialog box is displayed.
Figure 2: ASP. NET status server Properties dialog box
ASP. NET applications need to specify the TCP/IP address of the computer where the session Status Service is located. You must enter the following settings in the web. config file of the application.
Mode = "StateServer"
Stateconnectionstring = "TCPIP = expoware: 42424"/>;
The stateconnectionstring feature includes the IP address of the computer and the port used for data exchange. The default computer address is 127.0.0.1 (local host) and the default port is 42424. You can also specify the computer by name. For code, the use of local or remote computers is completely transparent. Note that the name cannot contain non-ASCII characters and the port number is mandatory.
If you use the out-of-process session storage, the session status will still exist and be available for future use, regardless of the situation of the ASP. NET auxiliary process. If the service is interrupted, the data is retained and automatically retrieved when the service is restored. However, if the status Provider Service stops or fails, data will be lost. If you want your application to have powerful functions, use the SQL Server mode instead of the StateServer mode.
Mode = "sqlserver"
Sqlconnectionstring = "Server = 127.0.0.1; uid = <user ID >;; Pwd = <password >;;"/>;
You can use the sqlconnectionstring feature to specify the connection string. Note that the feature string must contain the user ID, password, and server name. It cannot contain tags such as database and initial catalog, because this information is a fixed name by default. The user ID and password can be replaced with the integrated security settings.
How to Create a database? ASP. NET provides two pairs of scripts to configure the database environment. The first script is named installsqlstate. SQL and uninstallsqlstate. SQL, which are in the same folder as the session Status NT Service. They create a database named aspstate and several stored procedures. However, data is stored in the tempdb database in the temporary storage area of SQL Server. This means that session data will be lost if you restart the SQL server computer.
To address this limitation, use the second pair of scripts. The second pair of scripts are installpersistsqlstate. SQL and uninstallpersistsqlstate. SQL. In this case, the aspstate database is created, but data tables are created in the same database, and these data tables are also persistent. When SQL server support is installed for a session, a job is created to delete expired sessions in the session status database. The job name is aspstate_job_deleteexpiredsessions and runs continuously. Note that to make the job run properly, you need to run the SQLServerAgent service.
No matter which mode you select, the encoding method for session state operations will not change. You can always work on session attributes and read and write values as usual. All behavioral differences are processed at the lower abstraction layer. Status serialization may be the most important difference between session modes.
Status serialization and deserialization
When in-process mode is used, objects are stored in the session status as active instances of their respective classes. If real serialization and deserialization are not performed, it means that you can actually store any object you have created in the Session (including objects that cannot be serialized and COM objects ), in addition, the overhead for accessing them will not be too high. If you select an out-of-Process status provider, it is another situation.
In the out-of-process architecture, session values are copied from the local storage medium (external appdomain database) to the memory of the appdomain Processing request. This task needs to be completed using the serialization/deserialization layer, and represents a major cost of the off-process state provider. The main impact of this situation on code is that serializable objects can only be stored in the session dictionary.
According to the involved data types, ASP. NET uses two methods for data serialization and deserialization. For basic types, ASP. NET uses an optimized internal serialization program. For other types (including objects and user-defined classes), ASP. NET uses the. NET binary formatting program. The basic types include string, date and time, Boolean value, byte, character, and all numeric types. For these types, the serialization program created by using the volume itself is faster than using the common default. net binary formatting program.
The optimized serialization program is not publicly released or provided in document form. It is only a binary Reader/writer and uses a simple but effective storage architecture. The serialization program uses the binarywriter class to write a byte to indicate the type, and then write a byte to indicate the value corresponding to the type. When reading serialized bytes, the class first extracts one byte, detects the data type to be read, and then calls the specific readxxx method for the binaryreader class.
Note that the values of Boolean and numeric types are well known, but not for strings. On the Basic data stream, a string always carries a fixed-length prefix (write 7-bit integer code at a time). Based on this fact, the reader determines the correct size of the string. The date value is saved by writing only the total number of tags that constitute the date. Therefore, to serialize a session, the date must be of the int64 type.
As long as the included classes are marked as serialized classes, you can use the binaryformatter class to perform serialization operations on more complex objects (and custom objects. All non-basic types are identified using the same type ID and stored in the same data stream as the basic type. In short, serialization operations may cause a 15% to 25% reduction in performance. However, note that this is a rough estimate based on the assumption that the basic type is used. The more complex the use type, the higher the overhead.
If you do not use a large number of basic types, it is difficult to achieve effective session data storage. Therefore, at least theoretically, it is better to use three session slots to save three different string attributes of an object than to serialize the entire object. But what if the object to be serialized contains 100 attributes? Do you want to use 100 slots or only one slot? In many cases, a better way is to convert complex types into multiple simple types. This method is based on the type converter. A type converter is a lightweight serialization program that returns key type attributes in the form of a string set. A type converter is an external class that uses features to bind with the base class. The Type writers decide which attributes to save and how to save them. The type converter is also helpful for viewstate storage. It represents a more effective session storage method than binary formatting programs.
For ASP. NET session management, it is important that the lifecycle of the session state object starts only when the first item is added to the memory dictionary. The ASP. NET session starts only after the following code snippet is executed.
Session ["myslot"] = "some data ";
The session dictionary usually contains the object type. to read data backward, You need to convert the returned value to a more specific type.
String data = (string) session ["myslot"];
When the page saves data to the session, it loads the value to a special dictionary class contained in the httpsessionstate class. When the request is processed, the dictionary content is loaded into the status provider. If the session status is empty because the data is not put into the dictionary by programming, the data will not be serialized into the storage medium, and more importantly, it will not be stored in ASP.. Net cache, SQL Server, or NT status service. This is for performance reasons, but it will have an important impact on the way session IDs are processed: a new session ID will be generated for each request until some data is stored in the session dictionary.
When you need to connect the session status to the request being processed, the HTTP module will retrieve the session ID (if it is not a startup request) and search for it in the configured status provider. If no data is returned, the HTTP module generates a new session ID for the request. This can be easily tested on the following page:
<% @ Page Language = "C #" trace = "true" %>;
<Form runat = "server">;
<Asp: button runat = "server" text = "click"/>;
Whenever you click this button and return to the page, a new session ID is generated and tracking information is recorded.
Figure 3: a new session ID is generated for each request in an application that does not store data in the session dictionary.
What is the situation of the session_onstart event? Will this event be triggered for each request? If the application defines the session_onstart handler, the session status is always saved even if the session status is empty. Therefore, for all requests after the first request, the session ID is always a constant. The session_onstart handler is used only when necessary.
If a session times out or is abandoned, its session ID will not change the next time you access a stateless application. After the design, even if the session status expires, the session ID can continue until the browser session ends. That is to say, as long as the browser instance is the same, the same session ID is always used to represent multiple sessions.
The session_onend event indicates the end of the session and is used to execute all the cleanup Code required to terminate the session. Note that only the inproc mode supports this event, that is, this event is supported only when session data is stored in the ASP. NET auxiliary process. For the session_onend event to be triggered, the session state must exist first, which means that some data must be stored in the session state and at least one request must be completed.
In inproc mode, a variable expiration time policy is assigned to the session Status added to the cache as a project. The variable expiration time indicates that if a project is not used for a certain period of time, it will be deleted. The expiration time of any request processed during this period will be reset. The time interval of the session state item is set to session timeout. The technology used to reset the session state expiration time is very simple and intuitive: The session HTTP module only reads session state items stored in ASP. NET cache. If you know the internal structure of the ASP. NET cache object, this module performs computation to reset the variable expiration time. Therefore, when the cache project expires, the session has timed out.
Expired items are automatically deleted from the cache. As part of the project's expiration time policy, the status session module also represents a delete callback function. The cache automatically calls the delete function. Deleting the function triggers the session_onend event. If an application executes session management through an out-of-process component, the end event will never be triggered.
Each active ASP. NET session is identified by a 120-bit string consisting of only characters allowed by the URL. Session ID is generated using the random number generator (RNG) to encrypt the provider. The service provider returns a sequence containing 15 randomly generated numbers (15 bytes X 8-bit = 120 bits ). The random number array is mapped to a valid URL character and returned as a string.
The session ID string is sent to the browser and then returned to the server application in either of the following two ways: using cookies (just like in traditional ASP) or modified URLs. By default, the session Status Module creates an HTTP cookie on the client, but you can use the modified URL embedded in the session ID string (especially for browsers that do not support cookies ). The method depends on the configuration settings stored in the web. config file of the application. To configure session settings, you can use the <sessionstate>; section and cookieless features.
<Sessionstate cookieless = "True | false"/>;
By default, cookieless is set to false, indicating that the cookie is used. In fact, cookies are only a text file on the client's hard disk. In ASP. NET, cookies are represented by an instance of the httpcookie class. Generally, a cookie contains the name, value set, and expiration time. When the cookieless feature is set to false, the session Status Module will actually create a cookie named ASP. net_sessionid and store the session ID in it. The following pseudocode shows the cookie creation process:
Sessioncookie = new httpcookie ("ASP. net_sessionid", sessionid );
Sessioncookie. Path = "/";
The expiration time of session cookies is very short, and the expiration time is updated after each request is successful. The expires attribute of the cookie indicates the expiration time of the cookie on the client. If the session cookie is not explicitly set, the expires attribute defaults to datetime. minvalue, which is the minimum time unit allowed by. NET Framework.
To disable session cookies, set cookieless to true in the configuration file, as shown below:
<Sessionstate cookieless = "true"/>;
Assume that you request the page at the following URL:
The actual content displayed in the address bar of the browser varies, and the session ID is included as follows:
When the HTTP module of the session status is instantiated, this module checks the value of cookieless features. If it is true, the request is redirected (HTTP 302) to the modified virtual URL that contains the session ID (before the Page name. When the request is processed again, the request contains the session ID. If a request starts a new session, the HTTP module generates a new session ID and redirects the request. If the request is sent back, the session ID already exists because the relative URL is used for returning the request.
The disadvantage of cookieless session is that if an absolute URL is called, the session status will be lost. When using cookies, you can clear the address bar, go to another application, return to the previous application, and retrieve the same session value. If you disable session cookies, session data is lost. For example, the following code interrupts the session:
<A runat = "server" href = "/code/page. aspx">; click </a>;
If you need to use an absolute URL, use some tips to manually add the session ID to the URL. You can call the applyapppathmodifier method for the httpresponse class.
<A runat = "server"
Href = <% = response. applyapppathmodifier ("/code/page. aspx") % >;>; click </a>;
The applyapppathmodifier method uses a URL string and returns the absolute URL of the embedded session information. For example, this technique is particularly useful when you need to redirect from an HTTP page to an HTTPS page.
The session status was initially introduced by the traditional ASP, which is a dictionary-based API that enables developers to store custom data during a session. In ASP. NET, session Status supports the following two main functions: cookieless session ID storage and transmission, and the status provider for actual session data storage. To implement these two new functions, ASP. NET uses the HTTP module to control the binding between the session Status and the request context being processed.
In traditional ASP, session Status refers to Cookie usage. This is no longer the case in ASP. NET because the cookieless architecture can be used. With the strength of the HTTP module, you can break down the request URL to include the session ID and redirect it. Next, the HTTP module extracts the session ID from the URL and uses it to retrieve the status of any storage.
The physical status of a session can be stored in three locations: In-process memory, out-of-process memory, and SQL Server table. Data must be serialized/deserialized before it can be used by applications. The HTTP module copies the session value from the provider to the memory of the application at the beginning of the request. After the request is complete, the modified status will return to the provider. This data communication will adversely affect the performance to varying degrees, but it will greatly enhance the reliability and stability, and make it easier to support the Web farm and web garden architecture.
Start building with 50+ products and up to 12 months usage for Elastic Compute Service