Understanding State Management
You need to maintain state-level and page-level information of an ASP.NET Web
application because Web pages and ASP.NET Framework use HTTP protocol to
communicate between a Web browser and a Web server. HTTP is a stateless
protocol. Therefore it can not automatically indicate whether the sequential
requests are coming from the same or different clients. For example, if you need
to develop a Web application that provides a personalized page to users after
subsequent logon, you need to keep track of user activities when users access
the web page. You need to implement session tracking for each user accessing the
Web application because HTTP does not enable you to keep track of user
activities in a Web Page. In addition, a Web page is fetched again, each time
the page is posted to a Web server. This results in loss of information
associated with the page and the controls on the page with each round trip. For
example, if user selects a checkbox in a Web page, the selection will be lost in
the round trip of the page page.
To overcome this limitation, ASP.NET provides different state
management options.
State management options can be divided into two categories:
Client-Side management
Server-Side management
The following table lists the Client-side and server-side options:
|
CLIENT-SIDE
OPTIONS |
SERVER-SIDE OPTIONS |
|
View State property |
Application state |
|
Hidden Fields |
Session state |
|
Cookies |
Database support |
|
Query Strings |
|
Client-Side State Management Options
Client side state management options involve storing information either in a
Web page or on a Client computer. Client-side management gives a better
performance, as the load on the server is less. Disadvantage of this option is
that only limited data can be stored. The client-side options are as follows:
View State
The ViewState property of an ASP.NET web page enables you to retain page and
control-specific values between round trips. Each web page and the controls on
the page have the ViewState property that is inherited from the base Control
class. ASP.NET framework uses the ViewState property to automatically save the
values of the Web page and each control on the Web page prior to rendering the
page. During postback of a Web page to itself, one of the tasks performed by
ASP.NET is to restore the values in _VIEWSTATE.
The view state is implemented with a hidden form
field called _VIEWSTATE,
which is automatically created in every Web page. When ASP.NET executes a Web
page on a Web server, the values stored in the ViewState property of the page
and controls on it are collected and formatted into a single encoded string. The
encoded string is then assigned to the Value attribute of the hidden form
field _VIEWSTATE and is sent to the client as a part of the Web page. When page
is initialized during postback, ASP.NET Framework parses the ViewState string to
restore the property information in the page.
The view state of a Web page or a control
consists of the cumulative property values of the page or the control. To
preserve these values across stateless HTTP requests, Web pages and controls in
ASP.NET use an instance of the StateBag class. This class is the primary
storage mechanism for HTML and server controls. It stores attribute/value pairs
associated with HTML and server controls as strings. Therefore, this class is
used to manage the view state of an ASP.NET Web page and the controls added to
the page after the OnInit method is executed. When you add values to this class,
the values are automatically added to the hidden _VIEWSTATE form variable. The
syntax to add a value to the StateBag class is as follows:
ViewState["any string"] = "some value";
By default, the Viewstate property of both Web
page and the controls on the Web page is enabled.
Perform the following steps to determine the
effect of enabling and disabling the ViewState property in an ASP.NET web
application:
Create a new Web application.
Add a label and a button control to
Webform1.aspx. The label control and the button control should have the
default name, Label1 and Button1, repectively. Ensure that the EnableViewState
property of the Label and Button control are set to true. In addition, ensure
that the EnableViewState property to the Page is set to true.
Add the following lines of code in the load
event of the page and execute the application.
if(!IsPostBack)
{
Label1.Text="Hello";
}
When the page is first loaded in the memory of the client computer, the
message Hello is assigned to the Text property of the label control. However, if
you click the button and reload the page, the label continues to display the
message. It is because the Text property of the Label control, Label1 is
automatically preserved through the view state property of the control..
Now if you set the ViewState property of the label control to false and click
the button, the displayed text would not be "hello" but "Label", the default
text.
Advantages of using ViewState Control
The values in view state are stored in a standard HTML format as part of a
Web page. Therefore, no Web server resource is required to maintain it.
The view state can be easily implemented in the ASP.NET Web page. You just
need to set the EnableViewState property of a Web page and server controls.
The values in view state are hashed, compressed and encoded for Unicode
implementations. Therefore, values in view state are more secured than values
stored in hidden fields.
Limitations in using ViewState
Storing large values can cause a page to slow down when user display it or
post it because view state is stored in the page.
View State is stored in a hidden field in a page. Although view state
stores data in a hashed format. It can be tampered with. The information in
the hidden field can be seen if the page output source is viewed directly,
creating a potential security issue.
Hidden Fields
In ASP.NET, you can use the HTML-standard hidden fields in a Web form to
store page-specific information. A hidden field does not render in a Web
browser. However, you can set the properties of the hidden field. When a page is
submitted to the server, the content of a hidden field is sent in the HTTPForm
collection along with the values or other controls.
A hidden field stores a single variable in its value property and must be
explicitly added to the page. In ASP.NET, the HtmlInputHidden
control provides the hidden field functionality. Perform the following steps to
implement an HtmlInputHidden control to store page-specific information:
Create a new Web application and add a Text box and a button control to
the Webform1.aspx.
Add a hidden control onto the form form the HTML tab in the
toolbox.
Right click the hidden control and select the Run As Server Control
option form the short-cut menu.
Add a label control to the form.
Add the following lines of code in the load event of the page:
if (Page.IsPostBack)
{
Label1.Text="Hidden
Value: "+ Hidden1.Value; }
Hidden1.Value=TextBox1.Text;
When the application is executed and you click the button after entering any
text in the text box, the entered text id assigned to the Value property of the
HtmlInputHidden control. During the round trip of the Web page, the value
remains stored in the HtmlInputHidden control. At the time of loading the page,
the value stored in Hidden1 is assigned to the Text property of the Label1.
INtersetingly, when a user clicks the button wothout specifying the value in the
text box, label1 displays only the text Hidden Value without any
additional text. This is because the value of the text box is always assigned to
the hidden variable. In addition, when the page loads for the first time,
Page.IsPostBack will return false. Therefore, the text Hidden Value will not be
displayed.
Note: If you use hidden fields, you must submmit your pages to the
server using the HTTP POST method instead of requesting the page using
the page URL. You cannot take advantage of hidden fields if a page is processed
in response to a link or the HTTP GET method.
Advantages of using Hidden Form fields
Limitations in using Hidden form fields
You can view the information stored in the hidden field by accessing the
source of the Web page. Therefore, the values stored in hidden form fields are
not very secure.
The hidden field does not support more than a single value field to store
information.
The hidden fields are stored in a page. Therefore, storing large values in
hidden form fields can slow down the processing of the page.
Cookies
A cookie is used to store small piece of information on client machine. A
cookie contains page-specific information that a Web server sends to a client
along with page output. Cookies are used for sending page-specific information
because HTTP is a stateless protocol and cannot indicate whether page requests
are coming from the same or different clients. You can use cookies to keep track
of each individual user who access a Web page across an HTTP connection.
Cookies are saved on the Client computer. Cookies can either be
temporary or persistent. Temporary cookies, also known as session
cookies, exist in the memory space of a browser. When the browser is closed, all
session cookies added to the browser are lost. A persistent cookie is
saved as a text file in the file system of the client computer.
A Web browser can access a cookie from the HttpCookieCollection
by using the Request object. If a cookie is accessed using the Request
built-in object, the cookie is a read only file. The cookie is stored on the Web
browser and not on the Web server. However, if you want to modify a cookie, you
need to use the Response built in object.
Perform the following steps to create a persistent cookie on a client
computer and read the contents of the cookie:
HttpCookie mycookie=new
HttpCookie ("Cookiename","hello");
mycookie.Expires =System.Convert
.ToDateTime ("12/12/2007");
Response.Cookies.Add (mycookie);
HttpCookie myvar;
myvar=Request.Cookies
.Get ("Cookiename");
Response.Write ("Cookie
:" + myvar.Name + "<br>");
Response.Write ("Expires : " + myvar.Expires +
"<br>");
Now run the application.
When you execute the application, only a button is displayed in the Web
browser. After you click the button in the web form, a cookie with the name
Cookiename is created in the Cookies folder on the client computer. After the
cookie is created on the client computer, the details of the cookie, such as the
name and the expiry date of the cookie are displayed in the client browser.
Advantages of using Cookies
A cookie is stored on the client computer and can be read by the server
after a request for a page is posted. Therefore, no server resource is
involved in maintaining the cookie.
A cookie is a text-based data structure that contains key value pairs.
Therefore, it is easy to create and manipulate cookies.
A cookie can either expire when the browser session ends or exists
indefinitely on the client computer, subject to the expiration rules on the
client.
Limitations in using Cookies
Cookies that are stored on client computers have a limited size. Most
browsers allow cookies to have up to 4096 bytes in size. Therefore, you cannot
store a large amount of data in a cookie.
Users can disable cookies to prevent them from being stored on the hard disk
of their computer. If a user denies permission for cookies, an ASP.NET Web
application cannot store cookies on the client computer.
Users can tamper with cookies because cookies are stored on the client
computer.
Note: The above stated limitations of cookies are overcome in
ASP.NET by means of cookie-less property. If you set the cookie-less
property to TRUE, ASP.NET will embed the session id, normally stored in the
cookie, into the URL that is sent back to the client. When the client makes a
request using the URL containing the session id, ASP.NET is able to extract the
session id and map the request to the appropriate session data.
Query String
If you need to submit information back to a Web page or another page by using
a URL, you can use a query string. The query string is part of the request that
appears after the Question mark (?) character in the URL. A query string
provides a simple way to pass information from one page to another. For example,
in a logon screen, the user name can be passed to the next page in the
application by using query strings.
Perform the following steps to pass a user name form one page to another page
using query string:
In an ASP.NET Web application add one TextBox control and specify the ID
property as txtusername.
Add one label control to indicate the type of value the user needs to
enter in the TextBox control. Specify the Text property of the Label control
as Enter username.
Add another label control to display an error message when the user does
not enter any value in the TextBox control. Specify the ID of the label as
lblmsg. Delete the default text property of the control.
Add a Web form to the project by using the Add Web form option from the
project menu. Name it a mywebform.
Add a button control to WEbForm1.aspx and set the text property value as
Submit.
Add the following lines of code in the click event of Button1.
if
(txtusername.Text == "")
{
lblmsg.Text =
"Enter your name in the text box";
}
else
{
Response.Redirect ("mywebform.aspx?=name="+
System.Web.HttpUtility.UrlEncode (txtusername.text));
//The
HttpUtility class provides methods for encoding and decoding URLs when
processing Web requests.
}
In the above code, the Redirect method of the Response object is used to
redirect the execution of the Web application form WebForrm1.aspx Web page to
mywebform.aspx. The UrlEncode method of the HttUtility class is
used to pass the string entered in the txtusrname text box from WebForm1.aspx to
mywebform.aspx in an encoded format. Therefore when user enters a username
in the textbox control, the value that the user has entered is passed to the
mywebform.aspx web page as part of the URL.
If a user enters 'Richard' as the username and clicks the Submit button, mywebform.aspx is displayed with a URL as shown in the following figure (notice
the shaded blue portion) :
To ensure that query string values are available during page processing, you
must submit the page by using the HTTP Get method.
You can pass two or more name/value pairs using a query string. You can do this
by separating each pair with an ampersand (&). In this case the ned of the URL
might look like this:
?name=Richard&ID=A8135
Advantages of Query String
A query string is contained in the HTTP
request for a specific URL. Therefore, no server resource is involved to
process a query string.
Many Web browsers support passing values in a
query string. Therefore, if you create a Web application that passes
information from one page to another using a query string.
Limitations in using Query String
The information in a query string is directly
visible to the user in the browser window. Therefore, you need to encrypt this
information to ensure that any confidential information is not exposed to
strangers. This causes an additional overhead to Web application development.
There is a limit to the amount of information
that you can pass from one page to another using query strings because most
browsers support up to 255 characters of URL.
Server-Side State Management Options
There is a limit to client-side options, there are server-side state
management options. By using these options, you can manage application and
session-related information. Server-side options store information on the Web
server. These options are as follows:
Application State
ASP.NET provides Application state as a means of storing application
wide-specific information such as objects and variables. The information in the
application state is stored in a key-value pair and is used to maintain data
consistency between server round trips and between pages.
Application state is created when each browser request is made for a specific
URL. After an application state is created, the application-specific information
is stored in it. All information stored in the application state is shared among
all the pages of the Web application by using the HttpApplicationState class.
The HttpApplictaionState class is accessed using the Application property of the
HttpContext object. Variables and objects added to the application state are
global to an ASP.NET application. Syntax to create a variable and store
it in the application state:
Application["myvar"] =
"Hello";
After the application in which you declared
myvar is executed, any page contained in the application can retrieve the value
of the myvar. To read the value of the myvar, you need to use the following
statement:
Response.Write(Application["myvar"]);
You can also add complex objects, such as
Collection and Dataset, in application state. For example, you can add a dataset
to an application state by using the following statements:
DataSet ds =
new DataSet();
Application["DataSet"] = ds;
To remove the application variable myvar from the application state,
you need to use the following statement:
Application.Remove(["myvar"]);
or to remove all variable for application state wrote the following line of
code:
Application.RemoveAll();
It is important to note that after an object is added to an application
state, it remains in the application state until the application is shut down,
the Global.asax file is modified, or the item is explicitly removed from
the application state.
Since these variables are global to an
application, it is important to consider the following issues while storing any
value in an application state variable:
The memory occupied by variables stored in an
application state is not released until the value is either removed or
replaced. Therefore, the number of variables and objects in an application
state should be minimum. Otherwise, it will be an overhead on the Web server
and the server response will be slow.
Multiple pages within an application can
access values stored in an application state simultaneously. Therefore,
explicit synchronization methods need to be used to avoid deadlocks and access
violations.
The ASP.NET application supports events. Two
important events associated with ASP.NET application are discussed in the
following table:
|
EVENT |
DESCRIPTION |
|
Application_Start |
This event is triggered when an
application starts. If you want a code to be executed as the application
starts, you should add it to the Application_Start event. This event is
triggered only when the application starts and is not triggered again until
the IIS is stopped, the Global.asax file is modified, or the application is
unloaded. |
|
Application_End |
This event is triggered when an
application ends |
|
|
|
Application State and Synchronization
Multiple pages within an ASP.NET Web application can
simultaneously access values, stored in an application state. This can result in
conflicts and deadlocks. For example you can add a variable named
PageCounter in the application state to keep track of the number
of times a page has been requested. If two users access a Web page
simultaneously, there will be an attempt to update the value of the variable
PageCounter simultaneously. This will lead to a problem. To avoid such
situations, the HttpApplicationState class provides two methods, LOCK ( ) and
UNLOCK ( ). These methods only allow one thread at a time to access applications
state variables and objects.
Note: Each browser request for a Web page initiates a
new thread on the Web server.
Calling the Lock ( ) method on an Application object causes
ASP.NET to block attempts by the code running on other worker threads to access
anything in an application state. These threads are unblocked only when the
thread that called the Lock ( ) method calls the corresponding Unlock ( ) method
on the Application object.
The following example illustrates the use of the Lock ( )
method and the Unlock ( ) method:
Create a new ASP.NET Web application.
Add the following lines of code in the Page_Load event of
the page:
Application.Lock();
if(Application["PageCounter"]==null)
Application[
"PageCounter" ]=0;
Application[
"PageCounter" ]=(int)Application[
"PageCounter" ]+1;
Response.Write
(Application[ "PageCounter" ]);
Application.UnLock ();
In the preceding example, the Lock() method is first called
to ensure that the variable PageCounter cannot be simultaneously modified by
another thread. Next, the counter is increased by 1 and then the value is
displayed in the browser window. At last, the UnLock() methods is called to
release the imposed lock on the application state variable PageCounter. You can
notice the effect of Lock() and UnLock() methods by clicking the Refresh button
on the browser window. Each time you click the Refresh button, the value of the
PageCounter is incremented. You can open the same form in another window
by copying and pasting the URL, you will note that the value displayed will be
not 1 but 1 incremented to the value you left on the previous window.
Note: If you do not explicitly call the Unlock( )
method, the .NET Framework automatically removes the lock when the request
completes or times out, or when an unhandled error occurs during request
execution and causes the request to fail. This automatic unlocking prevents the
application from deadlocking.
You cannot selectively lock items in an application state,
the application state object as a whole is blocked.
Advantages of using Application state:
Limitations in using Application State:
Session State
In ASP.NET, session state is used to store session-specific information for a
Website. Unlike application state, the scope of session state is limited to the
current browser session. If different users are accessing a Web application,
each will have a different session state. In addition, if a user exits and
returns later, the user will have a different session state.
The session state has a built in support in ASP.NET. The built-in session
state feature automatically performs the following actions:
Identify and classify requests coming from a browser into a logical
application session on the server.
Store session-specific data on the server for use across multiple browser
requests.
Raise session lifetime-related events, such as Session_OnStart
and Session_OnEnd, which can be handled using application code.
A unique 120-bit SessionID string containing ASCII characters identifies and
tracks each active ASP.NET session. The following code can be used to add the
variable name myvar in the session state:
Session["myvar"] =
"HELLO";
To display the value of my var, you can use the following statement:
Response.Write(Session["myvar"]);
There are three issues that you need to consider
while adding variables and objects to a session state:
Any variable or object that you add to a
session state is available only until the user closes the browser window. The
variables and the objects are explicitly removed form session state if the
user does not requests a page for more than 20 minutes.
Any variable or object added to a session
state is related to a particular user. For example, you can store different
values for myvar for two different users accessing the Web page and each user
can access only the value that is assigned to him.
Any object that supports serialization can be
added to a session state. Since objects stored in a session state are stored
on the server, session objects are not subject to the same size limitations as
cookies.
Similar to he application state you can remove a
variable added to the session state by using the Remove ( ) or RemoveAll ( )
method.
Starting and Ending a User Session
A user session starts when a user requests the
first page from a Web Site. when the first page is requested, the Web
server adds the ASP.NET SessionID cookie to the client computer. The following
line enables you to view the value of session ID:
Response.Write(Session.SessionID);
You can use the Abandon() method of the
Session object to explicitly stop a user session, by using the following line of
code:
Session.Abandon();
You can also modify the Timeout property of the
Session object to change the default value of timeout i.e. 20 minutes.
To do this open the Web.Config file and
scroll to the <sessionState> section and modify the value of the Timeout
property as shown in the shaded portion of the figure below:
Handling Session events
Session states has the following events that you can capture to manipulate an
ASP.NET web application.:
Session_Start
Session_End
You can capture both these events by adding subroutines in the Global.asax
file. A practical demonstration in the end of this article would make the
usage of these events more clear.
You can also use the Session_Start subroutine to automatically redirect users
to a particular page when a user session begins.
Since the session data is stored on the Web server, and if the server crashes
the session data would be lost. To avoid this, you can store session data
in a separate Windows service. For this perform the following
steps:
Create a new ASP.NET web application. Search the ASP.NET State service and
click the Start Service button.
Modify the web.Config file to set the sessionstate mode to the value
StateServer and specify the location of the State Server in the
stateConnectionString.
When the State Server is used to store the session state data, the process
mode is InProc ( in-process), by default.
You can also manage session state out of process by storing data in a
Microsoft SQL Server database. The advantage is that you can cluster multiple
database servers so that if one fails, another can take over the state
management. For this change the mode property of sessionState in Web.config to
SQLServer.
By default session state is enabled for all pages of your application.
Although you can disable it by modifying the page directive as follows:
<%@
Page
EnableSessionState =
"False" %>
Advantages of using Session state:
It is event driven, therefore you can use session events to perform
conditional execution of user-defined tasks.
data in session state variables and objects can survive Web server
restarts without losing data.
Session states can be used in both multi-computer and multi-process
configurations.
A session state facility can work with browsers that do not support HTTP
cookies.
Limitations in using Session State:
Practical Demonstration
Here we'll build a simple page that resembles some of the characteristics of
a shopping cart. It will show number of items in the cart which may vary
according as per every user who's logged on to this page. We will also have a
button to remove items from the cart. I have kept it simple, and I am just
counting the number of items in the cart, you can do this by assigning the value
to the session variable as a DataSet or an Arraylist. For the sake of your
learning I will also show you the usage of application state and the session
events.
You can download example project from this link
.
This application keeps a track of the number of users who have visited the
site. Had you wanted to keep a track of just the active users, you could have
added the following line of code to the Session_End event.
Application["Counter"] = (int)Application["Counter"]-1; |