Monday, 28 October 2013

ASP.NET View State

 

 

What is state management?

Web is Stateless. It means a new instance of the web page class is re-created each time the page is posted to the server. As we all know HTTP is a stateless protocol, its can't holds the client information on page. As for example , if we enter a text and client on submit button, text does not appear after post back , only because of page is recreated on its round trip.

 

clip_image002

 

As given in above pages, page is recreated before its comes to clients and happened for each and every request. So it is a big issue to maintain the state of the page and information for a web application. That is the reason to start concept of State Management. To overcome this problem ASP.NET 2.0 Provides some features like View State, Cookies, Session, Application objects etc. to manage the state of page.

There are some few selection criteria to selected proper way to maintain the state, as there are many way to do that. Those criteria are:

· How much information do you need to store?

· Does the client accept persistent or in-memory cookies?

· Do you want to store the information on the client or on the server?

· Is the information sensitive?

· What performance and bandwidth criteria do you have for your application?

· What are the capabilities of the browsers and devices that you are targeting?

· Do you need to store information per user?

· How long do you need to store the information?

· Do you have a Web farm (multiple servers), a Web garden (multiple processes on one machine), or a single process that serves the application?

So, when ever you start to think about state management, you should think about above criteria. based on that you can choose the best approaches for manages state for your web application.

 

 

Different types of state management?

There are two different types of state management:

1. Client Side State Management

  1. o View State
  2. o Hidden Field
  3. o Cookies
  4. o Control State

2. Server Side State Management

  1. o Session
  2. o Application Object
  3. o Caching
  4. o Database

 

Client Side state management does not use any server resource , it store information using client side option. Server Side state management use server side resource for store data. Selection of client side and server side state management should be based on your requirements and the selection criteria that are already given.

 

 

What is view state?

View State is one of the most important and useful client side state management mechanism. It can store the page value at the time of post back (Sending and Receiving information from Server) of your page. ASP.NET pages provide the ViewState property as a built-in structure for automatically storing values between multiple requests for the same page.

 

Example:

 

If you want to add one variable in View State,

ViewState["Var"]=Count;

 

For Retrieving information from View State

string Test=ViewState["TestVal"];

 

Sometimes you may need to typecast ViewState Value to retreive. As I give an Example to strore and retreive object in view state  in the last of  this article.

 

 

Advantages of view state?


This are the main advantage of using View State:

· Easy to implement

· No server resources are required

· Enhanced security features ,like it can be encoded and compressed.

 

 

Disadvantages of view state?


This are the main disadvantages of using View State:

· It can be performance overhead if we are going to store larger amount of data , because it is associated with page only.

· Its stored in a hidden filed in hashed format (which I have discussed later) still it can be easily trapped.

· It does not have any support on mobile devices.

 

 

When we should use view state?


I already describe the criteria of selecting State management. A few point you should remember when you select view state for maintain your page state.

· Size of data should be small , because data are bind with page controls , so for larger amount of data it can be cause of performance overhead.

· Try to avoid storing secure data in view state

 

clip_image006


 


 


 


 


When we should avoid view state?


You won't need view state for a control for following cases,

· The control never change

· The control is repopulated on every postback

· The control is an input control and it changes only of user actions.

 


 


 


Where is view state stored?


View State stored the value of page controls as a string which is hashed and encoded in some hashing and encoding technology. It only contain information about page and its controls. Its does not have any interaction with server. It stays along with the page in the Client Browser. View State use Hidden field to store its information in a encoding format.

Suppose you have written a simple code , to store a value of control:

 


ViewState["Value"] = MyControl.Text;

 

Now, Run you application, In Browser, RighClick > View Source , You will get the following section of code

 

clip_image008


Fig : View state stored in hidden field

Now , look at the value. looks likes a encrypted string, This is Base64 Encoded string, this is not a encoded string. So it can easily be decoded. Base64 makes a string suitable for HTTP transfer plus it makes it a little hard to read . Read More about Base64 Encoding . Any body can decode that string and read the original value. so be careful about that. There is a security lack of view state.

 

 

How to store object in view state?


We can store an object easily as we can store string or integer type variable. But what we need ? we need to convert it into stream of byte. because as I already said , view state store information in hidden filed in the page. So we need to use Serialization. If object which we are trying to store in view state ,are not serializable , then we will get a error message .

 


Just take as example,

 


//Create a simple class and make it as Serializable

[Serializable]

public class student

{

    public int Roll;

    public string Name;

    public void AddStudent(int intRoll,int strName)

      {

        this.Roll=intRoll;

        this.Name=strName;

           }

}

Now we will try to store object of "Student" Class in a view state.

 

 


 //Store Student Class in View State

student _objStudent = new student();

_objStudent.AddStudent(2, "Abhijit");

ViewState["StudentObject"] = _objStudent;

 

//Retrieve Student information view state

 student _objStudent;

_objStudent = (student)ViewState["StudentObject"]; 

 

 

 

How to trace your view state information?


If you want to trace your view state information, by just enable "Trace" option of Page Directive

 

clip_image011


 

Now Run your web application, You can view the details of View State Size along with control ID in Control Tree Section. Don't worry about "Render Size Byte" , this only the size of rendered control.

clip_image013


Fig : View State Details

 


 


 


 


Enabling and Disabling View State


You can enable and disable View state for a single control as well as at page level also. To turnoff view state for a single control , set EnableViewState Property of that control to false. e.g.:

 


TextBox1.EnableViewState =false;

 

To turnoff the view state of entire page, we need to set EnableViewState to false of Page Directive as shown bellow.

 

clip_image015


 

Even you disable view state for the entire page , you will see the hidden view state tag with a small amount of information, ASP.NET always store the controls hierarchy for the page at minimum , even if view state is disabled.

For enabling the same, you have to use the same property just set them as True

as for example, for a single control we can enabled view state in following way,

 


TextBox1.EnableViewState =true;

 

and for a page level,

 

clip_image017


 


 


 


 


 


How to make view state secure?


As I already discuss View state information is stored in a hidden filed in a form of Base64 Encoding String, and it looks like:

clip_image018


Fig : View state stored in hidden field

 

Many of ASP.NET Programmers assume that this is an Encrypted format, but I am saying it again, that this is not a encrypted string. It can be break easily. To make your view state secure, There are two option for that,

· First, you can make sure that the view state information is tamper-proof by using "hash code". You can do this by adding "EnableViewStateMAC=true" with your page directive. MAC Stands for "Message Authentication Code"

 

clip_image020


 


A hash code , is a cryptographically strong checksum, which is calculated by ASP.NET and its added with the view state content and stored in hidden filed. At the time of next post back, the checksum data again verified , if there are some mismatch, Post back will be rejected. we can set this property to web.config file also.

· Second option is to set ViewStateEncryptionMode="Always" with your page directives, which will encrypt the view state data. You can add this in following way

 

clip_image022


 

It ViewStateEncryptionMode has three different options to set:

· Always

· Auto

· Never

Always, mean encrypt the view state always, Never means, Never encrypt the view state data and Auto Says , encrypt if any control request specially for encryption. For auto , control must call Page.RegisterRequiresViewStateEncryption() method for request encryption.

we can set the Setting for "EnableViewStateMAC" and ViewStateEncryptionMode" in web.config also.

 

clip_image024


Note : Try to avoid View State Encryption if not necessary , because it cause the performance issue

 

 


 


 


 


ASP.NET Page Life Cycle with State Management objects


 


Introducing Viewstate Outside the ASP.NET Context

In its very basic form, Viewstate is nothing more than a property which has a key/value pair indexer:

 


 


Viewstate[“mystringvariable”] = “myvalue”;

Viewstate[“myintegervariable”] = 1;

 

 

As you can see, the indexer accepts a string as a key and an object as the value. The ViewState property is defined in the “System.Web.UI.Control” class. Since all ASP.NET pages and controls derive from this class, they all have access to the ViewState property. The type of the ViewState property is “System.Web.UI.StateBag”.

The very special thing about the StateBag class is the ability to “track changes”. Tracking is, by nature, off; it can be turned on by calling the “TrackViewState()” method. Once tracking is on, it cannot be turned off. Only when tracking is on, any change to the StateBag value will cause that item to be marked as “Dirty”.


 







Info: In case you are wondering (and you should be) about the reason behind this “tracking” behavior of the StateBag, do not worry; this will be explained in detail along with examples about how tracking works, in the next sections.


 


 


 


Introducing Viewstate Inside the ASP.NET Context


 


When dealt within the context of ASP.NET, the Viewstate can be defined as the technique used by an ASP.NET web page to remember the change of state spanning multiple requests. As you know, ASP.NET is a stateless technology; meaning that two different requests (two postbacks) to the same web page are considered completely unrelated. This raises the need of a mechanism to track the change of state for this web page between the first and the second request.

The Viewstate of an ASP.NET page is created during the page life cycle, and saved into the rendered HTML using in the “__VIEWSTATE” hidden HTML field. The value stored in the “__VIEWSTATE” hidden field is the result of serialization of two types of data:

1. Any programmatic change of state of the ASP.NET page and its controls. (Tracking and “Dirty” items come into play here. This will be detailed later.)

2. Any data stored by the developer using the Viewstate property described previously.

This value is loaded during postbacks, and is used to preserve the state of the web page.


 







Info: The process of creating and loading the Viewstate during the page life cycle will be explained in detail later. Moreover, what type of information is saved in the Viewstate is also to be deeply discussed.


   

One final thing to be explained here is the fact that ASP.NET server controls use Viewstate to store the values of their properties. What does this mean? Well, if you take a look at the source code of the TextBox server control, for example, you will find that the “Text” property is defined like this:

   


public string Text

{

    get { return (string)ViewState["Text"]; }

    set { ViewState["Text"] = value; }

}

 

You should apply this rule when developing your own server controls. Now, this does not mean that the value of the “Text” property set at design time is saved in the rendered serialized ViewState field. For example, if you add the following TextBox to your ASP.NET page:

   


<asp:TextBox runat="server" ID="txt" Text="sometext" />

  

According to the fact that the “Text” property uses Viewstate to store its value, you might think that the value is actually serialized in the __VIEWSTATE hidden field. This is wrong because the data serialized in the hidden __VIEWSTATE consists only of state changes done programmatically. Design time data is not serialized into the __VIEWSTATE (more on this later). For now, just know that the above declaration of the “Text” property means that it is utilizing Viewstate in its basic form: an indexed property to store values much like the Hashtable collection does.


 


 


Generating the compiled class

The first step (actually, step 0 as explained in the info block below) of the life cycle is to generate the compiled class that represents the requested page. As you know, the ASPX page consists of a combination of HTML and Server controls. A dynamic compiled class is generated that represents this ASPX page. This compiled class is then stored in the “Temporary ASP.NET Files” folder. As long as the ASPX page is not modified (or the application itself is restarted, in which case the request will actually be the first request and then the generation of the class will occur again), then future requests to the ASPX page will be served by the same compiled class.


 







Info: If you have read my previous article about request processing, you will likely recall that the last step of the request handling is to find a suitable HTTP Handler to handle the request. Back then, I explained how the HTTP Handler Factory will either locate a compiled class that represents the requested page or will compile the class in the case of the first request. Well, do you see the link? This is the compiled class discussed here. So, as you may have concluded, this step of generating the compiled class actually occurs during the ASP.NET request handling architecture. You can think of this step as the intersection between where the ASP.NET request handling architecture stops and the ASP.NET page life cycle starts.


 

This compiled class will actually contain the programmatic definition of the controls defined in the aspx page. In order to fully understand the process of dynamic generation, let us consider the following example of a simple ASPX page for collecting the username and the password:

 

clip_image001


 

Now, upon the first request for the above page, the generated class is created and stored in the following location:

 


C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\


         <application name>\< folder identifier1>\< file identifier1>.cs

The compiled class “DLL” is also created in the same location with the same file identifier, as follows:

 

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\


         <application name>\< folder identifier1>\< file identifier1>.dll

 

As you can see, the generated class and its corresponding DLL are created, and will serve any new request for the ASPX page until one of the following conditions occur:


· The ASPX file is modified

· The application is restarted, for example, as a result of IIS reset or app domain restart


The following code is extracted from the compiled class. Note that the code is reformatted and “cleaned up” for presentation purposes.

 

clip_image004


 

 

OK, so now is the really interesting part. Start examining the code above, and you will be able to notice the following:

· The class – unsurprisingly – inherits from the “System.Web.IHttpHandler”. As explained earlier, this makes it eligible for acting as an HTTP Handler for the request.

· All the controls – both HTML and Web Controls – are defined in the class. Notice how the static properties (such as “Text” and “TextMode”) are set inside the class. This is very important to remember because this is a vital point when discussing the Viewstate later in this article.

· The “BuildControlTree” is called to create the control hierarchy. As you may know, controls inside an ASPX page are built into a tree hierarchy. For example, in the above example, the hierarchy would be as follows: The root parent is the page class itself, under which the direct child controls are the HTML Literal (the "b" tag) and the HTML Form. The HTML Form, in its turn, has two direct child controls which are the HTML Literal (the "div" tag) and the HTML Table. The HTML Table, in its turn, has child controls such as the Web Control for the username label and the Web Control for the password label, and so on until the complete hierarchy is built. Again, this is a very important point to remember because it will be revisited when discussing the Viewstate.

 

PreInit (New to ASP.NET 2.0)

The entry point of the page life cycle is the pre-initialization phase called “PreInit”. This is the only event where programmatic access to master pages and themes is allowed. Note that this event is not recursive, meaning that it is accessible only for the page itself and not for any of its child controls.

 

Init (Recursive)

Next is the initialization phase called “Init”. The “Init” event is fired reclusively for the page itself and for all the child controls in the hierarchy (which is created during the creation of the compiled class, as explained earlier). Note that against many developers’ beliefs, the event is fired in a bottom to up manner and not an up to bottom within the hierarchy. This means that following up with our previous example, the “Init” event is fired first for the most bottom control in the hierarchy, and then fired up the hierarchy until it is fired for the page itself. You can test this behavior yourself by adding a custom or user control to the page. Override the “OnInit” event handler in both the page and the custom (or user) control, and add break points to both event handlers. Issue a request against the page, and you will notice that the event handler for the control will be fired up before that of the page.

 

InitComplete (New to ASP.NET 2.0)

The initialization complete event called “InitComplete” signals the end of the initialization phase. It is at the start of this event that tracking of the ASP.NET Viewstate is turned on. Recall that the StateBag class (the Type of Viewstate) has a tracking ability which is off by default, and is turned on by calling the “TrackViewState()” method. Also recall that, only when tracking is enabled will any change to a Viewstate key mark the item as “Dirty”. Well, it is at the start of “InitComplete” where “Page.TrackViewState()” is called, enabling tracking for the page Viewstate.


 







Info: Later, I will give detailed samples of how the Viewstate works within each of the events of the life cycle. These examples will hopefully aid in understanding the inner workings of the Viewstate.


 

LoadViewState

This event happens only at postbacks. This is a recursive event, much like the “Init” event. In this event, the Viewstate which has been saved in the __VIEWSTATE during the previous page visit (via the SaveViewState event) is loaded and then populated into the control hierarchy.

 

LoadPostbackdata (Recursive)

This event happens only at postbacks. This is a recursive event much like the “Init” event. During this event, the posted form data is loaded into the appropriate controls. For example, assume that, on your form, you had a TextBox server control, and you entered some text inside the TextBox and posted the form. The text you have entered is what is called postback data. This text is loaded during the LoadPostbackdata event and handed to the TextBox. This is why when you post a form, you find that the posted data is loaded again into the appropriate controls. This behavior applies to most controls like the selected item of a drop down list or the “checked” state of a check box, etc…

A very common conceptual error is the thought that Viewstate is responsible for preserving posted data. This is absolutely false; Viewstate has nothing to do with it. If you want a proof, disable the Viewstate on your TextBox control or even on the entire page, and you will find that the posted data is still preserved. This is the virtue of the LoadPostbackdata event.

 

PreLoad (New to ASP.NET 2.0)

This event indicates the end of system level initialization.

 

Load (Recursive)

This event is recursive much like the “Init” event. The important thing to note about this event is the fact that by now, the page has been restored to its previous state in case of postbacks. That is because the LoadViewState and the LoadPostbackdata events are fired, which means that the page Viewstate and postback data are now handed to the page controls.

 

RaisePostbackEvent

This event is fired only at postbacks. What this event does is inspect all child controls of the page and determine if they need to fire any postback events. If it finds such controls, then these controls fire their events. For example, if you have a page with a Button server control and you click this button causing a postback, then the RaisePostbackEvent inspects the page and finds that the Button control has actually raised a postback event – in this case, the Button's Click event. The Button's Click event is fired at this stage.

 

LoadComplete (New to ASP.NET 2.0)

This event signals the end of Load.

 

Prerender (New to ASP.NET 2.0)

This event allows for last updates before the page is rendered.

 

PrerenderComplete (New to ASP.NET 2.0)

This event signals the end of “Prerender”.

 

SaveViewstate (Recursive)

This event is recursive, much like the “Init” event. During this event, the Viewstate of the page is constructed and serialized into the __VIEWSTATE hidden field.


 







Info: Again, what exactly goes into the __VIEWSTATE field will be discussed later.


 

SaveStateControl (New to ASP.NET 2.0)

State Control is a new feature of ASP.NET 2.0. In ASP.NET 1.1, Viewstate was used to store two kinds of state information for a control:

 


· Functionality state

· UI state


 

This resulted in a fairly large __VIEWSTATE field. A very good example is the DataGrid server control. In ASP.NET 1.1, DataGrid uses the Viewstate to store its UI state such as sorting and paging. So, even if you wanted to disable Viewstate on the DataGrid and rebind the data source on each postback, you simply cannot do that if your DataGrid was using sorting or paging. The result was that the DataGrid ended up using Viewstate to store both its bounded data and its UI state such as sorting and paging.

 

ASP.NET 2.0 solved this problem by partitioning the Viewstate into two:


· The Viewstate we are discussing here

· The Control State


 

The Control State is used to store the UI state of a control such as the sorting and paging of a DataGrid. In this case, you can safely disable the DataGrid Viewstate (provided, of course, that you rebind the data source at each postback), and the sorting and paging will still work simply because they are saved in the Control State.

The Control State is also serialized and stored in the same __VIEWSTATE hidden field. The Control State cannot be set off.

 

Render (Recursive)

This is a recursive event much like the “Init” event. During this event, the HTML that is returned to the client requesting the page is generated.

 

Unload (Recursive)

This is a recursive event much like the “Init” event. This event unloads the page from memory, and releases any used resources.

 

 

 

Role of Viewstate in the Page Life Cycle


 


Viewstate in the “Init” event

The important thing to note in the “Init” event is that Viewstate tracking is not yet enabled. In order to demonstrate this, let us take the following example:

 


protected override void OnInit(EventArgs e)

(

    bool ret;

    ret = ViewState.IsItemDirty("item");//returns false

    ViewSTate["item"] = "1";

    ret = ViewState.IsItemDirty("item");returns false

    base.OnInit(e);

}

 

Note that in the above example, the item is still not marked as “Dirty” even after it is being set. This is due to the fact that at this stage, the “TrackViewState()” method is not called yet. It will be called in the “InitComplete” event.


 







Info: You can force the tracking of Viewstate at any stage that you want. For example, you can call the “Page.TrackViewState()” method at the start of the “Init” event and thus enabling tracking. In this case, the “Init” event will behave exactly like the “InitComplete” event, to be discussed next.


 

 

Viewstate in the “InitComplete” event

In the “InitComplete” event, the Viewstate tracking is enabled. If we take the same example:

 


protected override void OnInitComplete(EventArgs e)


(

    bool ret;

    ret = ViewState.IsItemDirty("item");//returns false

    ViewSTate["item"] = "1";

    ret = ViewState.IsItemDirty("item");//returns true

 

    base.OnInitComplete(e);

}

 

This time, note that first, the item is not marked as “Dirty”. However, once it is set, then it is marked as “Dirty”. This is due to the fact that at the start of this event, the “TrackViewState()” method is called.

 

 

Viewstate in the “LoadViewState”and “SaveViewState” events

 


To better understand the role of Viewstate in these events, let us take an example. Say that you have a simple ASPX page that consists of the following:

· A Label server control with its “Text” property set to “statictext”

· A Button server control just to postback the page

· The “Load” event of the page has a statement that sets the “Text” property of the Label control to “dynamictext”. This statement is wrapped inside a “!IsPostback” condition

 

 

When the page first loads, the following will happen:

· During the “Load” event, the “dynamictext” value will be assigned to the “Text” property of the Label

· Later in the life cycle, the “SaveViewSatte” event is fired, and it stores the new assigned value “dynamictext” in the __VIEWSTATE serialized field (in the next sections, you will see how tracking came into play here)

 

 

Now, when you click the Button control, the following will happen:

· The “LoadViewState” event is fired. The __VIEWSTATE value saved in the previous page visit is loaded. The “dynamictext” value is extracted and assigned back to the “Text” property of the Label.

· The “Load” event is fired, but nothing happens there because the code is wrapped inside a “!IsPostback” condition.

See how that because of the Viewstate, the “dynamictext” value is persisted across page postback. Without Viewstate and with the “!IsPostback” condition inside the “Load” event, the value “dynamictext” would have been lost after the postback.

 

 

Viewstate Walkthroughs


OK, so by now, you should have a solid understanding about the page life cycle, the Viewstate, and the role of the Viewstate in the page life cycle. However, we are yet to discuss the cases that tests whether you are an advanced Viewstate user or not. In the next walkthroughs, you shall tackle most of these cases. By the end of this section, you can safely call yourself an advanced Viewstate user.

 

Walkthrough 1: Viewstate of an empty or Viewstate-disabled page

So, let us start by a very simple question. Will you have a value stored in the __VIEWSTATE field if you have a blank ASP.NET page or a page with Viewstate completely disabled? The answer is yes. As a test, create a blank ASP.NET page and run it. Open the View Source page and note the __VIEWSTATE field. You will notice that it contains a small serialized value. The reason is that the page itself saves 20 or so bytes of information into the __VIEWSTATE field, which it uses to distribute postback data and Viewstate values to the correct controls upon postback. So, even for a blank page or a page with disabled Viewstate, you will see a few remaining bytes in the __VIEWSTATE field.

 

Walkthrough 2: What is stored in the Viewstate?

As mentioned previously, the data stored in the __VIEWSTATE field consists of the following:

 


· Data stored by developers using the Viewstate[“”] indexer

· Programmatic change to the Control State

 


While the former is pretty much clear, the latter is to be explained thoroughly.

OK, so let us assume that you have a web page with only a Label control on it. Now, let us say that at design time, you set the “Text” property of the Label to “statictext”. Now, load the page and open the View Source page. You will see the __VIEWSTATE field. Do you think “statictext” is saved there? The answer is, for sure, not. Recall from our discussion about generating the compiled class of the page, that static properties of controls are assigned at the generated class? So, when the page is requested, the values stored in the generated class are displayed. As such, static properties that are set at design time are never stored in the __VIEWSTATE field. However, they are stored in the generated compiled class, and thus they show up when rendering the page.

Now, let us say that you did some changes to your page such that it consists of the following:


· A Label control with the value “statictext” assigned to its “Text” property

· A Button control to postback the page


· Inside the “Page_Load” event handler of the page, add code to change the value of the Label’s “Text” property to “dynamictext”. Wrap this code inside a “!IsPostback” condition.

Load the page and open the View Source page. This time, you will notice that the __VIEWSTATE field is larger. This is because at runtime, you changed the value of the “Text” property. And, since you have done this inside the “Load” event, where, at this time, tracking of Viewstate is enabled (remember, tracking is enabled in the “InitComplete” event), the “Text” property is marked as “Dirty”, and thus the “SaveViewstate” event stores its new value in the __VIEWSTATE field. Interesting!!

As a proof that the “dynamictext” value is stored in the __VIEWSTATE field (apart from the fact that it is larger), click the Button control causing a postback. You will find that the “dynamictext” value is retained in the Label even though the code in the “Load” event is wrapped inside the “!IsPostback” condition. This is due to the fact that upon postback, the “LoadViewstate” event extracted the value “dynamictext” which was saved by the “SaveViewState” event during the previous page visit and then assigned it back to the Label’s “Text” property.

Let us now go one step further. Repeat the exact same scenario, with one exception: instead of adding the code that will change the value of the “Text” property at the “Page_Load” event handler, override the “OnPreInit” event handler and add the code there. Now, first load the page, and you will see the new text displayed in the Label. But, do you think this time it is stored in the __VIEWSTATE field? The answer is no. The reason is that during the “PreInit” event, Viewstate tracking is not yet enabled, so the change done to the “Text” property is not tracked and thus not saved during the “SaveViewState” event. As a proof, click the Button causing a postback. You will see that the value displayed inside the Label is the design time value “statictext”.

Let us even go one step further. If you have been following this long article carefully, you will recall that during the “Init” event, tracking of Viewstate is not yet enabled. You have even seen an example in the section Viewstate in the “Init” event of how an item keeps being not dirty even after it is being set. Now, going back to our current example, you will most probably be tempted to consider that if we add the code that changes the value of the “Text” property inside the “OnInit” event handler, you will get the same result as when you put it inside the “OnPreInit” event handler; after all, tracking of Viewstate is not enabled yet during either event. Well, if you think so, then you are mistaken. Reason: if you have been following this article carefully, you will recall that the “InitComplete” event (where tracking of Viewstate is enabled) is not a recursive event; it is called only for the page itself, but not for its child controls. This means that, for the child controls, there is no “InitComplete” event; so, where does the tracking of Viewstate start? The answer is at the start of the “Init” event. So, this means that for the page itself, tracking of Viewstate is enabled at the “InitComplete” event; that is why during the “OnInit” event handler, the item was still marked as not being “Dirty” even after modification. However, for child controls, there is no “InitComplete” event, so the Viewstate tracking is enabled as early as the “Init” event. And, since – again as was explained earlier – the “Init” event is called recursively for the page and its controls in a bottom to up manner, by the time the “Init” event of the page itself is fired, the “Init” event of the child controls is already being fired, and thus Viewstate tracking for child controls is on by that time. As such, adding the code that changes the value of the “Text” property inside the “OnInit” event handler will have the same effect as putting it inside the “Page_Load” event handler.

 

Walkthorugh 3: What is the larger Viewstate?

Consider the following example: you have two ASP.NET pages: page1.aspx and page2.aspx. Both pages contain only a single Label control. However, in page1, the Label is declared at design time with its “Text” property set to a small string (say 10 characters); in page2, the Label is declared at design time with its “Text” property set to a lengthy string (say 1000 characters). Now, load both pages at the same time, and examine the View Source for both pages. Compare the two __VIEWSTATE fields, what do you find? You will find that both fields are of the same size even though one Label has its “Text” property storing 10 characters while the other has its “Text” property storing 1000 characters. If you have read walkthroughs 1 and 2, you will for sure know the reason: design time property values are not stored in the Viewstate. The __VIEWSTATE value for both pages is simply the bytes emitted by the page itself.

 

Walkthrough 4: Complete page life cycle scenario

In this walkthrough, we will go through each of the relevant page life cycle events and see what role Viewstate has in each of these events. In this example, we have as ASP.NET page with the following characteristics:


· It contains a single Label control (lbl) with its “Text” property set to “statictext”

· It contains a Button control (btnA) with code in its event handler that sets the “Text” property of “lbl” to “dynamictext”

· It contains a Button control (btnB) whose purpose is to cause a page postback

Now, let us examine what will happen during the page life cycle.

1. The page is first loaded

1. The compiled class of the page is generated and “statictext” is assigned to “lbl.Text

2. Tracking for Viewstate is enabled in the “InitComplete” event

3. “LoadViewState” is not fired because there is no postback

4. “SaveViewstate” is fired, but nothing happens because no change of state is recorded

5. The page is rendered with the value “statictext” inside “lbl

2. btnA is clicked

1. The previously generated compiled class is handed the request; “lbl.Text” is set to “statictext”

2. Tracking for Viewstate is enabled

3. “LoadViewState” is fired, but nothing happens because no change of state was recorded in the previous page visit

4. “RaisePostbackEvent” event is executed and “btnA” click event handler is fired; “lbl.Text” is set to “dynamictext”; since tracking is enabled at this stage, this item is tracked (marked as “Dirty”).

5. “SaveViewState” is fired; “dynamictext” is serialized and stored in the __VIEWSTATE field

6. The page is rendered with the value “dynamictext” inside “lbl

3. btnB is clicked

1. The previously generated compiled class is handed the request; “lbl.Text” is set to “statictext”

2. Tracking for Viewstate is enabled

3. “LoadViewState” is fired; since a change of state was recorded from the previous page visit, __VIEWSTATE is loaded and the value “dynamictext” is extracted; this value is then assigned to “lbl

4. “RaisePostbackEvent” event is executed; nothing happens here because “btnB” has no event handler for its “Click” event

5. “SaveViewState” is fired, but nothing happens because no change of state is recorded

6. The page is rendered with the value “dynamictext” inside “lbl


 

 

Walkthrough 5: Reducing Viewstate size – Disabling Viewstate

Disabling Viewstate would obviously reduce Viewstate size; but, it surely kills the functionality along the way. So, a little more planning is required…

Consider the case where you have a page with a drop down list that should display the countries of the world. On the “Page_Load” event handler, you bind the drop down list to a data source that contains the countries of the world; the code that does the binding is wrapped inside a “!IsPostback” condition. Finally, on the page, you have a button that when clicked should read the selected country from the drop down list. With the setup described above, you will end up with a large __VIEWSTATE field. This is due to the fact that data bound controls (like the drop down list) store their state inside the Viewstate. You want to reduce Viewstate; what options do you have?

1. Option 1: Simply disable the Viewstate on the drop down list

2. Option 2: Disable the Viewstate on the drop down list, and remove the “!IsPostback” condition

3. Option 3: Disable the Viewstate on the drop down list, and move the binding code without the “!IsPostback” condition to the “OnInit” or “OnPreInit” event handlers

If you implement Option 1, you will reduce the Viewstate alright, but with it, you will also lose the list of countries on the first postback of the page. When the page first loads, the code in the “Page_Load” event handler is executed and the list of countries is bound to the list. However, because Viewstate is disabled on the list, this change of state is not saved during the “SaveViewState” event. When the button on the page is clicked causing a postback, since the binding code is wrapped inside a “!IsPostback” condition, the “LoadViewState” event has nothing saved from the previous page visit and the drop down list is empty.

 

If you implement Option 2, you will reduce the Viewstate size and you will not lose the list of countries on postback. However, another problem arises: because the binding code is now executed at each “Page_Load”, the postback data is lost upon postback, and every time, the first item of the list will be selected. This is true because in the page life cycle, the “LoadPostbackdata” event occurs before the “Load” event.

 

Option 3 is the correct option. In this option, you have done the following:

· Disabled Viewstate on the drop down list

· Removed the “!IsPostback” condition from the binding code

· Moved the binding code to the “OnInit” event handler (or the “OnPreInit” event handler)

Since the “Init” event occurs before the “LoadPostbackdata” in the page life cycle, the postback data is preserved upon postbacks, and the selected item from the list is correctly preserved.

Now, remember that in Option 3, you have successfully reduced the Viewstate size and kept the functionality working; but, this actually comes at the cost of rebinding the drop down list at each postback. The performance hit of revisiting the data source at each postback is nothing when compared with the performance boost gained from saving a huge amount of bytes being rendered at the client’s __VIEWSTATE field. This is especially true with the fact that most clients are connected to the Internet via low speed dial up connections.

 

 

Walkthrough 6: Viewstate and Dynamic Controls

The first fact that you should know about dynamic controls is that they should be added to the page at each and every page execution. Never wrap the code that initializes and adds the dynamic control to the page inside a “!IsPostback” condition. The reason is that since the control is dynamic, it is not included in the compiled class generated for the page. So, the control should be added at every page execution for it to be available in the final control tree. The second fact is that dynamic controls play “catch-up” with the page life cycle once they are added. Say, you did the following:

 


Label lbl = new Label();


Page.Controls.Add(lbl);

 

Once the control is added to the “Controls” collection, it plays “catch-up” with the page life cycle, and all the events that it missed are fired. This leads to a very important conclusion: you can add dynamic controls at any time during the page life cycle until the “PreRender” event. Even when you add the dynamic control in the “PreRender” event, once the control is added to the “Controls” collection, the “Init”, “LoadViewState”, “LoadPostbackdata”, “Load”, and “SaveViewstate” are fired for this control. This is called “catch-up”. Note though that it is recommended that you add your dynamic controls during the “PreInit” or “Init” events. This is because it is best to add controls to the control tree before tracking of the Viewstate of other controls is enabled…

Finally, what is the best practice for adding dynamic controls regarding Viewstate? Let us say that you want to add a Label at runtime and assign a value to its “Text” property. What is the best practice to do so? If you are thinking the below, then you are mistaken:

 



Label lbl = new Label();

Page.Controls.Add(lbl);

lbl.Text = "bad idea";

 

You are mistaken because using the above technique you are actually storing the value of the “Text” property in the Vewstate. Why? Because, recall that once a dynamic control is added to the “Controls” collection, a “catch-up” happens and the tracking for the Viewstate starts. So, setting the value of the “Text” property will cause the value to be stored in the Viewstate.

However, if you do the below, then you are thinking the right way, because you are setting the “Text” property before adding the control to the “Controls” collection. In this case, the value of the “Text” property is added with the control to the control tree and not persisted in Viewstate.

 



Label lbl = new Label();

lbl.Text = "good idea";

Page.Controls.Add(lbl);

 


 


Blogger Labels: View,State,management,instance,server,protocol,client,information,example,text,clients,concept,Provides,Cookies,Session,Application,selection,criteria,Does,memory,performance,capabilities,user,servers,machine,Different,Side,Hidden,Field,Control,Object,Database,resource,option,data,requirements,mechanism,ViewState,Count,Test,TestVal,Sometimes,Value,article,Advantages,advantage,Easy,resources,Disadvantages,Size,Where,technology,interaction,Browser,Suppose,MyControl,RighClick,Source,Read,integer,Serialization,error,message,Just,Create,Serializable,student,Roll,Name,AddStudent,Class,_objStudent,Abhijit,StudentObject,Retrieve,Trace,Page,Directive,Tree,Section,Render,Byte,Details,turnoff,Enable,EnableViewState,hierarchy,True,Many,Programmers,Stands,Authentication,Code,mismatch,Post,Second,EncryptionMode,options,Auto,Says,RegisterRequires,Encryption,method,Note,Life,Cycle,Outside,Context,System,StateBag,Track,Once,item,Info,examples,Inside,technique,HTML,items,developer,Moreover,fact,properties,TextBox,Design,declaration,Hashtable,collection,ASPX,combination,Temporary,Files,folder,generation,Handler,Back,Factory,architecture,intersection,definition,password,location,WINDOWS,Microsoft,Framework,domain,presentation,purposes,Start,IHttpHandler,Controls,Notice,TextMode,BuildControlTree,Literal,Form,Table,Again,PreInit,phase,event,themes,Init,Recursive,creation,developers,manner,custom,Override,OnInit,handlers,Issue,InitComplete,Recall,Type,Also,Later,events,workings,LoadViewState,Save,LoadPostbackdata,virtue,PreLoad,Load,RaisePostbackEvent,Button,Click,LoadComplete,Prerender,PrerenderComplete,SaveViewstate,SaveStateControl,kinds,DataGrid,Unload,Role,EventArgs,OnInitComplete,Label,statement,IsPostback,SaveViewSatte,Walkthroughs,Walkthrough,Open,Programmatic,discussion,Page_Load,Wrap,Repeat,scenario,exception,OnPreInit,Reason,modification,Walkthorugh,Consider,Both,Compare,Complete,characteristics,purpose,setup,Disable,cost,Internet,Dynamic,execution,conclusion,Vewstate,retreive,postback,intRoll,strName,checksum,config,indexer,behavior,postbacks,username,upon,initialization,rebind,bool,statictext,dynamictext,bytes,runtime,btnA,btnB

1 comment:

  1. This blog gives very important info about .Net Thanks for sharing
    .Net Online Training

    ReplyDelete