Implementing session-State fundamentals in asp.net

Source: Internet
Author: User
Tags config empty http cookie httpcontext session id new features time interval port number
asp.net introduction

In a stateless environment such as WEB applications, understanding the concept of Session state has no practical significance. However, effective state management is an essential 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 on a per-user and per-application basis.

It is particularly noteworthy that the session state of the WEB application is the data that the application caches and retrieves in different requests. A session represents all requests sent by a user during a connection to the site, which is a collection of persistent data that the user generates and uses during the session. The state of each session is independent of each other and ceases to exist at the end of the user's session.
Session state does not correspond to any logical entities that make up HTTP protocols and specifications. A session is a server-side development environment, such as traditional ASP and ASP. NET) to build the abstraction layer. The way in which the asp.net shows the state and how the session state is implemented internally depends on the infrastructure of the platform. As a result, traditional ASP and ASP.net implement session state in a completely different way, which is expected to be further improved and enhanced in the next release of ASP.net.

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 State Overview

Session state is not part of the HTTP infrastructure. That is, there should be a struct component that binds the session state to each incoming request. Runtime Environment (traditional ASP or ASP. NET) can accept keywords such as the session and use it to indicate blocks of data stored on the server. To successfully resolve a call to a Session object, the Run-time environment must add the conversation state to the invocation context of the request being processed. This is done in a way that varies by platform, but it is the underlying operation of a stateful WEB application.

In traditional ASP, session state is implemented as a free thread COM object contained in the Asp.dll library. (Are you curious about this?) In fact, the CLSID of the object is D97a6da0-a865-11cf-83af-00a0c90c2bd8. This object stores data that is organized as a collection of name/value pairs. The name placeholder represents the keyword used to retrieve information, and the value placeholder represents what is stored in the session state. Name/value pairs are grouped by session ID, so that each user sees only the name/value pairs that he or she created themselves.

In ASP.net, the programming interface for session state is almost the same as the traditional ASP. But their underlying implementations are completely different, and the former are more flexible, scalable, and more programming-capable than the latter. Before delving into the asp.net session state, let's briefly review some of the structural features of the ASP.net session infrastructure.

In ASP.net, any incoming HTTP requests are transmitted through the HTTP module pipeline. Each module can filter and modify the amount of information that the request carries. The information associated with each request is called the call context, which is represented programmatically with the HttpContext object. We should not treat the context of the request as another container for state information, although it provides a collection of Items that is only a data container. The HttpContext object differs from all other state objects (for example, session, application, and Cache) because its finite lifecycle exceeds the time it takes to process the request. When a request passes through a series of registered HTTP modules, its HttpContext object will contain a reference to the state object. When the request is finally ready to be processed, the associated invocation context is bound to a particular session and global State object (application and Cache).

The HTTP module that is responsible for setting the session state of each user is sessionstatemodule. The structure of the module is designed based on the IHttpModule interface, which provides a large number of session-state-related services for asp.net applications. This includes generating session IDs, cookieless session management, retrieving session data from an external state provider, and binding data to the requested invocation context.

The HTTP module does not store session data internally. Session state is always saved in an external component named "State provider." The state provider fully encapsulates session-state data and communicates with other parts by means of the Istateclientmanager interface. The session state HTTP module invokes a method on this interface to read and save session state. ASP.net 1.1 supports three different state providers, as shown in table 1.

Table 1: State client Providers

Provider Description InProc session value in the ASP.net worker process (Microsoft? Windows Server? The aspnet_wp.exe or W3wp.exe in 2003) remains in memory as the active object. This is the default option. The StateServer session value is serialized and stored in the memory of a separate process (Aspnet_state.exe). The process can also run on other computers. SQL Server session values are serialized and stored at Microsoft? SQL Server? Table. Instances of SQL Server can be run locally or remotely.
The session state HTTP module will be from the <sessionState> of the Web.config file; Partially reads the currently selected status provider.

<sessionstate mode= "InProc | StateServer | SQL Server/>;

Depending on the value of the mode attribute, session state is retrieved from different processes and stored in a different process through different steps. By default, session state is stored in the local asp.net worker process. In special cases, it is stored in a private slot in the ASP.net Cache object (which cannot be accessed programmatically). You can also store session state externally, even in a remote process (for example, in a Windows NT service named Aspnet_state.exe). The third option is to store session state in a private database table managed by SQL Server 2000.

The HTTP module deserializes the session values at the beginning of the request, making them a Dictionary object. The dictionary is then accessed programmatically by the property session that is displayed by the class (for example, HttpContext and Page), which is actually an object of the HttpSessionState type. The binding between the session-state value and the session object visible to the developer persists until the end of the request. If the request completes successfully, all status values are serialized back to the status provider and can be used for other requests.

Figure 1 illustrates the communication between the requested ASP.net page session value. Each page uses code that is associated with the session property on the Page class. It is programmed in almost the same way as the traditional ASP.


The session-state architecture in Figure 1:asp.net 1.1

The physical value of the session state is locked during the time required to complete the request. The lock is internally managed by the HTTP module and is used to synchronize access to session state.

The session state module instantiates the state provider for the application and initializes it using the information read from the Web.config file. Next, each provider will continue its own initialization operation. A provider is a different type and its initialization can vary greatly. For example, the SQL Server state Manager will open a connection to a given database, and the Out-of-process Manager will check for the specified TCP port. On the other hand, the InProc state Manager stores a reference to the callback function. This action is performed when an element is removed from the cache and is used to trigger the application's Session_OnEnd event.





Synchronizing Access session state

What happens when a Web page makes a very simple and intuitive call to the session property? Many operations are done in the background, as shown in the following cumbersome code:

int sitecount = Convert.ToInt32 (session["Counter"]);

The above code actually accesses a copy of the session value created by the HTTP module in local memory, reading the data from a specific state provider (see Figure 1). What if other pages are also trying to synchronize access to the session state? In this case, the current request may stop processing inconsistent data or obsolete data. To avoid this, the session-state module implements a reader/writer locking mechanism and queues access to state values. A page with write access to the session state retains the writer lock on the session until the request terminates.

By setting the EnableSessionState property of the @Page directive to true, the page can request write permission for session state. (This is the default setting). However, a page can also have read-only access to session state, for example, when the EnableSessionState property is set to ReadOnly. In this case, the module retains the reader lock for the session until the page's request is finished. The result will be concurrent reads.

If a page request sets a reader lock, other requests that are processed concurrently in the same session will not be able to update the session state, but can be read at least. That is, if a read-only request for a session is currently being processed, a waiting read-only request has a higher priority than a request that requires full access. If a page request sets a writer lock for session state, all other pages will be blocked regardless of whether they want to read or write to the content. For example, if there are two frames that attempt to write content in the session, a frame must wait until another frame completes before it can be written.

Comparison status provider

By default, the ASP.net application stores session state in the memory of the worker process, especially in the Cache object's private slot. When InProc mode is selected, session state is stored in a slot within the Cache object. This slot is marked as a private slot and cannot be accessed programmatically. In other words, if you enumerate all the items in the ASP.net data cache, any objects similar to the state of a given session will not be returned. The Cache object provides two types of slots: dedicated slots and public slots. Programmers can add and process public slots, but private slots can only be dedicated to the system (especially the classes defined in the system.web part).

The state of each active session occupies a private slot in the cache. The name of the slot is named based on the session ID, whose value is an instance of an internal undeclared class named Sessionstateitem. The InProc state provider obtains the session ID and retrieves the corresponding element in the cache. The contents of the Sessionstateitem object are then entered into the HttpSessionState Dictionary object and accessed by the application through the session property. Note that there is an error in ASP.net 1.0 so that the private slots for the Cache object can be enumerated programmatically. If you run the following code under ASP.net 1.0, you can enumerate the items that correspond to the objects contained in each currently active session state.

foreach (DictionaryEntry elem in Cache)
{
Response.Write (Elem. Key + ":" + elem. Value.tostring ());
}

This error has been resolved in ASP.net 1.1, and any system slots will no longer be listed when you enumerate the cached content.

So far, InProc may be the quickest access option. However, keep in mind that the more data stored in a session, the more memory the WEB server consumes, potentially increasing the risk of performance degradation. If you plan to use any out-of-process solution, you should carefully consider the possible impact of serialization and deserialization. Out-of-process Solutions use Windows NT Service (aspnet_state.exe) or SQL Server tables to store session values. As a result, session state remains outside the ASP.net worker process and requires an additional layer of code to serialize and deserialize between session state and the actual storage media. This action occurs as long as the request is processed and must then be optimized to the highest degree.

Because the session data needs to be replicated from the external repository to the local session dictionary, the request causes performance degradation of 15% (out-of-process) to 25% (SQL Server). Please note that while this is only a rough estimate, it should be close to the minimum effect and the maximum impact will be much higher. In fact, this estimate does not fully consider the complexity of the type actually saved in the session state.

In an out-of-process storage scenario, the session state survives longer and makes the application more powerful because it protects against Microsoft? Internet Information Services (IIS) and ASP.net failed. By separating session state from your application, you can also make it easier to extend existing applications into Web Farm and web Garden architectures. In addition, session state is stored in an external process, fundamentally eliminating the risk of periodic data loss due to a process cycle.

The following describes how to use Windows NT services. As mentioned earlier, the NT service is a process called aspnet_state.exe, which is typically located in the C:\WINNT\Microsoft.NET\Framework\v1.1.4322 folder.

The actual directory depends on the version of the Microsoft? NET Framework that you are actually running. Before using the state server, make sure that the service is ready and running on the local or remote computer that is used as the session storage device. The status service is part of the ASP.net and is installed with it, so 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 will attempt to establish a connection with the state server immediately after it is loaded. Therefore, the service must be ready and running, or an HTTP exception will be thrown. The following illustration shows the Properties dialog box for the service.


Figure 2:asp.net State Server Properties dialog box

The ASP.net application needs to specify the TCP/IP address of the computer on which the session state service resides. The following settings must be entered in the application's Web.config file.

<configuration>;
<system.web>;
<sessionstate
Mode= "StateServer"
stateconnectionstring= "tcpip=expoware:42424"/>;
</system.web>;
</configuration>;

The stateConnectionString attribute contains 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 indicate the computer by name. For code, using a local or remote computer is completely transparent. Note that non-ASCII characters cannot be used in this name, and the port number is mandatory.

If you use Out-of-process session storage, session state will still exist and be available for future use, regardless of what happens to the ASP.net worker process. If the service is interrupted, the data is preserved and retrieved automatically when the service resumes. However, if the state provider service stops or fails, the data is lost. If you want your application to have powerful features, use SQL Server mode instead of StateServer mode.

<configuration>;
<system.web>;
<sessionstate
mode= "SQL Server"
sqlconnectionstring= "Server=127.0.0.1;uid=<user id>;; Pwd= <password>;; "/>;
</system.web>;
</configuration>;

You can specify the connection string through the sqlConnectionString attribute. Note that the attribute string must contain a user ID, password, and server name. It cannot contain tags such as Database and Initial Catalog, because this information defaults to a fixed name. The user ID and password can be replaced with the integrated security settings.

How do I create a database? ASP.net provides two pairs of scripts to configure the database environment. The first pair of feet is called InstallSqlState.sql and UninstallSqlState.sql, and the session state NT service is located in the same folder. They create a database named ASPState and a few stored procedures. However, the data is stored in the SQL Server temporary storage area TempDB database. This means that if you restart the SQL Server computer, the session data will be lost.

To address this limitation, use a second pair of scripts. The second pair of feet is called InstallPersistSqlState.sql and UninstallPersistSqlState.sql. In this case, the ASPState database is created, but the data tables are created in the same database, and the data tables are also persistent. When you install SQL Server support for a session, a job is also created to delete expired sessions in the session-state database. The job is named Aspstate_job_deleteexpiredsessions and runs all the time. Note that for this job to work properly, you need to run the SQLServerAgent service.

Regardless of which mode you choose, the way you encode the session-State action does not change. You can always work on the session property and read and write values as usual. All behavioral differences are handled at lower levels of abstraction. State serialization may be the most important difference between conversational patterns.


State serialization and deserialization

When using in-process mode, objects are stored in session state as active instances of their respective classes. If true serialization and deserialization do not occur, you can actually store any objects you create in the session (including objects that cannot be serialized and COM objects), and the overhead of accessing them is not too high. If you select an Out-of-process status provider, it is another case.

In an out-of-process architecture, session values are copied from the local storage media (external AppDomain database) to the AppDomain memory that handles the request. You need to complete the task with a serialization/deserialization layer and represent a major cost for the out-of-process state provider. The main effect of this situation on code is that only serializable objects can be stored in the session dictionary.

Depending on the type of data involved, ASP.net uses two methods to serialize and deserialize data. For basic types, ASP.net uses an optimized internal serializer, and for other types, including objects and user-defined classes, ASP.net uses the. NET binary Formatter. The base type includes a String, DateTime, Boolean, Byte, character, and all numeric types. For these types, using a tailored serializer is faster than using the default common. NET binary formatter.

Optimized serializers are not published publicly and are not provided in document form. It is just a binary reader/writer and uses a simple but efficient storage schema. The serializer uses the BinaryWriter class to write a byte representation type, and then writes a byte representing the corresponding value of that type. When reading a serialized byte, the class first extracts a byte, detects the data type to read, and then invokes a specific type of readxxx method on the BinaryReader class.

Note that the size of the Boolean and numeric types is well known, but not for strings. On the underlying data stream, the string always has a fixed-length prefix (7-bit integer code written one at a time), based on which the reader determines the correct size of the string. Date values are saved by writing only the total number of tags that make up the date. Therefore, to perform a serialization operation on a session, the date should be the Int64 type.

You can use the BinaryFormatter class to perform serialization operations on more complex objects (and custom objects), as long as you mark the contained classes as serializable. All non-basic types are identified by the same type ID and stored in the same data stream as the base type. In summary, serialization can result in a performance drop of 15% to 25%. Note, however, that this is a rough estimate based on the assumption that the base type is used. The more complex the type you use, the greater the overhead.

Effective session data storage is difficult to implement without extensive use of basic types. Therefore, at least in theory, it is better to serialize the object's three different string properties using three session slots than the entire object. But what if the object being serialized contains 100 properties? Do you want to use 100 slots or just one slot? In many cases, a better approach is to convert complex types to multiple simple types. This method is based on a type converter. A type converter is a lightweight serializer that returns key attributes of a type as a collection of strings. A type converter is an external class that uses attributes to bind to a base class. The type writer decides which properties to save and how to save them. A type converter is also useful for ViewState storage, which represents a more efficient method of session storage than a binary formatter.

The life cycle of a session

With regard to asp.net session management, it is important that the life cycle of the session-state object begin only when the first item is added to the memory dictionary. The asp.net session can be considered to begin only after executing the following snippet.

session["Myslot"] = "Some data";

The session dictionary usually contains the Object type, and to read the data backwards, you need to convert the returned value to a more specific type.

String data = (string) session["Myslot"];

When a page saves data to the session, it loads the value into a specially-crafted dictionary class contained in the HttpSessionState class. When the current processing request is completed, the contents of the dictionary are loaded into the status provider. If the session state is empty because the data is not put into the dictionary programmatically, the data is not serialized to the storage medium, and more importantly, the slot is not created in the ASP.net Cache, SQL Server, or NT State service to track the current session. This is for performance reasons but has a significant impact on the way session IDs are processed: A new session ID is generated for each request until some data is stored in the session dictionary.

When a session state needs to be connected to a request being processed, the HTTP module retrieves the session ID (if it is not a startup request) and looks for it in the configured state provider. If no data is returned, the HTTP module will generate a new session ID for the request. This can be easily tested through the following pages:

<%@ Page language= "C #" trace= "true"%>;
<body>;
<form runat= "Server";
<asp:button runat= "Server" text= "click"/>;
</form>;
</body>;

Whenever you click the button and return to the page, a new session ID is generated and the trace information is logged.


Figure 3: A new session ID is generated for each request in an application that does not have data stored in the session dictionary.

What about the Session_OnStart incident? Will this event also be raised for each request? If an application defines a Session_OnStart handler, session state is always saved, even if the session state is empty. Therefore, the session ID is always constant for all requests after the first request. Use the Session_OnStart handler only when it is really necessary.

If the session times out or is discarded, the next time a stateless application is accessed, its session ID does not change. After design, the session ID lasts until the end of the browser session, even if the session state expires. That is, as long as the browser instance is the same, the same session ID is always used to represent multiple sessions.

The Session_OnEnd event marks the end of the session and is used to perform all the purge code required to terminate the session. Note, however, that only the INPROC mode supports this event, that is, the event is supported only when the session data is stored in the ASP.net worker process. For the Session_OnEnd event to be raised, the session state must first exist, which means that some data must be stored in the session state, and at least one request must be completed.

In InProc mode, the session state that is added to the cache as a project is given a variable expiration policy. Variable expiration indicates that an item will be deleted if it is not in use for a certain period of time. The expiration time of any requests processed during this period will be reset. The time interval for the session-state item is set to the session timeout. The technique used to reset session-state expiration is simple and intuitive: the session HTTP module reads only the session-state items stored in the ASP.net Cache. If you know the internal structure of the ASP.net Cache object, the module evaluates to reset the variable expiration time. Therefore, the session has timed out when the cached item expires.

Expired items are automatically removed from the cache. The status session module, which is part of the expiration policy for this project, also represents a delete callback function. The cache will automatically call the delete function, delete the function, and then raise the Session_OnEnd event. If an application performs session management through an out-of-process component, the end event is never raised.


Cookieless session

Each active asp.net session is identified with a 120-bit string consisting of only the characters allowed by the URL. The session ID is generated using the random number generator (RNG) cryptographic provider. The service provider returns a sequence containing 15 randomly generated numbers (15 bytes x 8 bits = 120 bits). The array of random numbers is then 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 one of the following two ways: using cookies (as in traditional ASP) or modified URLs. By default, the session-state module creates an HTTP Cookie on the client, but you can use a modified URL that embeds the session ID string (especially for browsers that do not support cookies). Which method is used depends on the configuration settings stored in the application's Web.config file. To configure session settings, you can use <sessionState>; section and cookieless characteristics.

<sessionstate cookieless= "True|false"/>;

By default, the cookieless attribute is false, indicating that a Cookie was used. In fact, cookies are just a text file that a Web page puts on the client's hard disk. In asp.net, cookies are represented by an instance of the HttpCookie class. Typically, a Cookie contains a name, a collection of values, and an expiration time. When the cookieless attribute is set to False, the session-state module will actually create a Cookie named Asp.net_sessionid and store the session ID in it. The following pseudocode shows the process of creating cookies:

HttpCookie Sessioncookie;
Sessioncookie = new HttpCookie ("Asp.net_sessionid", SessionId);
Sessioncookie.path = "/";

The session Cookie has a short expiration time and updates the expiration date after each request succeeds. The Expires property of the cookie indicates the expiration time of the cookie on the client. If the session Cookie,expires property is not explicitly set, the default is Datetime.minvalue, the minimum time unit allowed by the. NET Framework.

To disable session cookies, set the cookieless attribute to true in the configuration file, as follows:

<configuration>;
<system.web>;
<sessionstate cookieless= "true"/>;
</system.web>;
</configuration>;

At this point, suppose you request a page at the following URL:

Http://www.contoso.com/sample.aspx

The actual content displayed in the browser's address bar is different, and now contains the session ID, as follows:

http://www.contoso.com/(5ylg0455mrvws1uz5mmaau45)/sample.aspx

When the session-State HTTP module is instantiated, the module examines the value of the cookieless attribute. True to request redirection (HTTP 302) to a modified virtual URL that contains the session ID (immediately before the page name). When the request is processed again, the session ID is included in the request. If a request starts a new session, the HTTP module generates a new session ID and then redirects the request. If a postback request is made, the session ID already exists because the postback uses a relative URL.

The disadvantage of using cookieless sessions is that if an absolute URL is invoked, session state is lost. When using cookies, you can clear the address bar, go to another application, and then return to the previous application and retrieve the same session value. If this is done when the session Cookie is disabled, 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, add the session ID to the URL manually by using some tips. You can call the Applyapppathmodifier method on the HttpResponse class.

<a Runat= "Server"
href=<% =response.applyapppathmodifier ("/code/page.aspx")%>; > Click </a>;

The Applyapppathmodifier method uses a string that represents the URL and returns an absolute URL that embeds the session information. This technique is particularly useful, for example, when you need to redirect from an HTTP page to an HTTPS page.

Summary

Session state was originally introduced by traditional ASP, a dictionary based API that allows developers to store custom data during sessions. In ASP.net, session state supports the following two main features: cookieless session ID storage and transport, and state providers that the session data is actually stored in. To implement both of these new features, ASP.net uses the HTTP module to control the binding between session state and the request context being processed.

In traditional ASP, using session state means using cookies. This is no longer the case in ASP.net, because the cookieless schema can be used. With the power of the HTTP module, you can decompose the requested URL so that it contains the session ID and then redirect it. Next, the HTTP module extracts the session ID from the URL and uses it to retrieve any stored state.

The physical state of a session can be stored in three locations: in-process memory, out-of-process memory, and SQL Server tables. The data must be serialized/deserialized to be used by the application. The HTTP module copies the session value from the provider to the application's memory at the start of the request. After the request completes, the modified state returns the provider. This data communication can have varying degrees of negative impact on performance, but it can greatly enhance reliability and stability and make support for Web Farm and Web Garden architectures easier to implement.



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.