cookieChoices = {};

Friday, 20 September 2013

State Managment in ASP

HTTP is a stateless protocol. Once the server serves any request from the user, it cleans up all the resources used to serve that request. These resources include the objects created during that request, the memory allocated during that request, etc. For a guy coming from a background of Windows application development, this could come as a big surprise because there is no way he could rely on objects and member variables alone to keep track of the current state of the application.
If we have to track the users' information between page visits and even on multiple visits of the same page, then we need to use the State management techniques provided by ASP.NET. State management is the process by which ASP.NET let the developers maintain state and page information over multiple request for the same or different pages.

Types of State Management

There are mainly two types of state management that ASP.NET provides:
  1. Client side state management
  2. Server side state management
When we use client side state management, the state related information will be stored on client side. This information will travel back and forth with every request and response. This can be visualized as:
client side
Note: Image taken from Microsoft press' Book.
The major benefit of having this kind of state management is that we relieve the server from the burden of keeping the state related information, it saves a lot of server memory. The downside of client side state management is that it takes more bandwidth as considerable amount of data is traveling back and forth. But there is one more problem which is bigger than the bandwidth usage problem. The client side state management makes the information travel back and forth and hence this information can be intercepted by anyone in between. So there is no way we can store the sensitive information like passwords, creditcard number and payable amount on client side, we need server side state management for such things.
Server side state management, in contrast to client side, keeps all the information in user memory. The downside of this is more memory usage on server and the benefit is that users' confidential and sensitive information is secure.
client side
Note: Image taken from Microsoft press' Book.
We cannot say that we will use any one type of state management in our application. We will have to find a mix of client side and server side state management depending on the type and size of information. Now let us look at what are the different ways we can manage state on client side and server side.

Client side state management techniques

  • View State
  • Control State
  • Hidden fields
  • Cookies
  • Query Strings

Server side state management techniques

  • Application State
  • Session State

View State

ASP.NET uses this mechanism to track the values of the controls on the web page between page request for same page. We can also add custom values to view state. ASP.NET framework takes care of storing the information of controls in view state and retrieving it back from viewstate before rendering on postback.
If we need to use viewstate to store our information, we just need to remember that the viewstate is adictionary object. We can have our data stored as key value pair in viewstate (see code below). The controls information is also being hashed into this dictionary during request and populated back during response.
Since this information is stored in the web page itself, ASP.NET encrypts the information. We can tweak the encryption related parameters from web.config.
<Configuration>
       <system.web>
        <pages viewStateEncryptionMode="Always"/>
      </system.web>
</configuration>
or page declarative:
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" ViewStateEncryptionMode="Always"%> 
Let us now look at a small implementation for viewstate. We have a simple web page with a textbox and abutton. The idea is that we will write something in the text box and see how ASP.NET stores this information in view state. We will store our own information in the view state too. When we run the page and write my name in thetextbox and press the button, a postback occurs but my name still remains in the textboxViewstate made that possible so after postback, the page looks like:
client side
When we look at the source, the view state looks like:
<input type="hidden" name="__VIEWSTATE"
id="__VIEWSTATE" value="/wEPDwUKMTkwNjc4NTIwMWRkfIZa4Yq8wUbdaypyAjKouH5Vn1Y=" />
Now let us try to add our own information in the viewstate. Let's keep track of users' postback on this page. Whenever user will hit a button, we will add 1 to the stored pot back value. The way to do would be:
protected void Page_Load(object sender, EventArgs e)
{
    if(IsPostBack == true)
    {
        if (ViewState["number"] != null) //Lets retrieve, increase and store again
        {
            ViewState["number"] = Convert.ToInt32(ViewState["number"]) + 1;
        }
        else //First postback, lets store the info
        {
            ViewState["number"] = 1;
        }

        Label1.Text = ViewState["number"].ToString();
    }
}
When we run the page and hit the button to do a postback, the web will show us the postbacks being done so far which is being stored in viewstate:
client side
View State is enabled by default, but we can disable it by setting the EnableViewState property for each web control to false. This reduces the server processing time and decreases page size.

Control State

We now know what a viewstate is and we also know that we can disable viewstate for controls on the page. But imagine if we are developing a custom control and we internally are using viewstate to store some information but the user of the control can disable the viewstate for our control. To avoid this problem, we can have viewstatelike behavior which cannot be disabled by control users and it is called ControlState. Control states lies inside custom controls and work the same as viewstate works.
To use control state in a custom control, we have to override the OnInit method and call theRegisterRequiresControlState method during initialization. Then we have to override the SaveControlStateand LoadControlState methods.

Hidden Fields

Hidden field are the controls provided by the ASP.NET and they let use store some information in them. The only constraint on hidden filed is that it will keep the information when HTTP post is being done, i.e., button clicks. It will not work with HTTP get. Let us do the same exercise of keeping track of postbacks using HiddenFields now.
(NoteViewState also uses hidden field underneath.)
//Store in Hidden Field -----------------------------------------------------------
int newVal = Convert.ToInt32(HiddenField1.Value) + 1; //Hidden field default value was 0
HiddenField1.Value = newVal.ToString();
Label2.Text = HiddenField1.Value;
client side
When we run the page and hit the button to do a postback, the web will show us the postbacks being done so far which is being stored in Hiddenfields (See code for details).

Cookies

There are scenarios when we need to store the data between page requests. So far, the techniques we have discussed store the data for the single page requests. Now we look at the techniques that store information between page requests.
Cookies are small pieces of information that can be stored in a text file on users' computer. The information can be accessed by the server and can be utilized to store information that is required between page visits and between multiple visits on the same page by the user. Let us do the same exercise of keeping track of postback by using cookies.
int postbacks = 0;
if (Request.Cookies["number"] != null) //Lets retrieve, increase and store again
{
    postbacks = Convert.ToInt32(Request.Cookies["number"].Value) + 1;
}
else //First postback, lets store the info
{
    postbacks = 1;
}
Response.Cookies["number"].Value = postbacks.ToString();

Label3.Text = Response.Cookies["number"].Value;
client side
We cannot keep track of postbacks using cookies as cookies will stay on user machine, so essentially we are looking at the number of times user POSTED back on their page so far since the beginning.
When we run the page and hit the button to do a postback, the web will show us the postbacks being done so far which is being stored in Cookies (see code for details). The cookies can have various parameters like how long they are valid and when should they expire. These parameters can be manipulated as:
Response.Cookies["number"].Expires = DateTime.Now.AddDays(1); 
This cookie will expire after 1 day of its creation.

Query Strings

Query strings are commonly used to store variables that identify specific pages, such as search terms or page numbers. A query string is information that is appended to the end of a page URL. They can be used to store/pass information from one page to another to even the same page. Let us work on storing the postback information in querystrings now:
//GetDataItem from querystring
if (Request.QueryString["number"] != null) //Lets retrieve, increase and store again
{
    Label4.Text = Request.QueryString["number"];
}

//set in query string
int postbacks = 0;

if (Request.QueryString["number"] != null) //Lets retrieve, increase and store again
{
    postbacks = Convert.ToInt32(Request.QueryString["number"]) + 1;
}
else //First postback, lets store the info
{
    postbacks = 1;
}

Response.Redirect("default.aspx?number=" + postbacks);
One thing to notice here is that we can no way store the postback information in the query string we are dealing with same page. The reason is that the query string creates a new URL each time and it will be a fresh request each time we use query strings. SO we are now essentially tracking number of click here. The idea behind query string is to pass small information to OTHER pages that can be used to populate information on that page.
client side
NOTE: The use of cookies and querystring here are just for the purpose of demonstration. In real scenarios, they should never be used to store information required for same page. The Querystrings should be used to store the information between multiple page visits. Cookies should be used to store information between multiple visits to our website from the same computer.

Application State

ASP.NET allows us to save values using application state. A global storage mechanism that is accessible from all pages in the Web application. Application state is stored in the Application key/value dictionary. This information will also be available to all the users of the website. In case we need user specific information, then we better use sessionstate.
ASP.NET provides three events that enable you to initialize Application variables (free resources when the application shuts down) and respond to Application errors:
  • Application_Start: Raised when the application starts. This is the perfect place to initialize Applicationvariables.
  • Application_End: Raised when an application shuts down. Use this to free application resources and perform logging.
  • Application_Error: Raised when an unhandled error occurs. Use this to perform error logging.
Let us now store the information of postbacks in application state:
//global.asax
void Application_Start(object sender, EventArgs e)
{
    Application["number"] = 0;
}

//In web pages
Application.Lock();
Application["number"] = Convert.ToInt32(Application["number"]) + 1;
Application.UnLock();

Label5.Text = Application["number"].ToString();
client side
When we run the page and hit the button to do a postback, the web will show us the postbacks being done so far which is being stored in ApplicationState. We can use this object to keep track of clicks by all users on the entire website (see code for details).

Session State

Like Application state, this information is also in a global storage that is accessible from all pages in the Web application. Session state is stored in the Sessionkey/value dictionary. This information will be available to the current user only, i.e., current session only.
//global.asax
void Session_Start(object sender, EventArgs e)
{
    // Code that runs when a new session is started
    Session["number"] = 0;
}

// Web forms
Session["number"] = Convert.ToInt32(Session["number"]) + 1;

Label6.Text = Session["number"].ToString();
client side
When we run the page and hit the button to do a postback, the web will show us the postbacks being done so far which is being stored in SessionState. We can use this object to keep track of clicks by the current user, i.e., who owns the session for the entire website (see code for details).

Advantages of Client Side State Management

  • Better scalability
  • Support for multiple browser

Advantages of Server Side State Management

  • Better security
  • Reduced bandwidth

No comments:

Post a Comment