Sunday, January 11, 2009

Understanding the ASP.NET Architecture Part - 4

View State

View state is an ASP.NET feature that allows a Web page to retain all of its state values between requests to the Web server. In classic ASP, developers are forced to handle this task manually, which is a tedious and time-consuming process.

Consider one example, where the user fills out a form with several HTML input text controls.
Once the form is submitted to the server, the ASP engine retrieves the control contents from the HTTP headers and processes the business logic.

When the page returns to the client, the control values (including user input) are not retained, unless the developer has manually rehydrated the control values using embedded server-side code within the HTML form.

This issue is a regular headache for form-based applications because the server commonly needs to return control values to the client for a second look—for example, if the user input fails server-side validation.
Input controls represent one of the simpler problems.

Drop-down list controls pose a more complicated problem because they contain multiple values and include a user-selected value. Typically, drop-down lists need to be hydrated just once, and they must then retain the same values and user selections.

Classic ASP requires you to manually repopulate the select box contents between postings to the server.
This requirement is not just tedious for the developer, but it can also be expensive for the server, especially if additional database lookups are required.

View state enables all controls on a Web page to retain their state values between successive postbacks to the server. Furthermore, view state preserves a control's properties between postbacks. For example, if a control's Visible property is set to "False," then the control will remain invisible between successive postbacks.

In short, view state saves developers time by reducing the amount of coding they have to do. In addition, view state improves application performance by eliminating the database calls that would otherwise be needed to rehydrate controls between postbacks.

How View State Works

View state is stored using encoded key-value pairs within a hidden form field. Every control on the page is represented using one or more pairs. For view state to work, a Web page must contain a server-side form (with the runat=server attribute) so that a hidden _VIEWSTATE field may be added directly below the opening tag.

(A server-side form is provided by default when you create a new Web page). View state only works for server-side controls contained within the server-side form. In fact, server-side controls will generate compilation errors if they are added to a page outside of their server-side form.

For a Web page with view state enabled, the view state process works as follows:
  1. The client requests a Web page.
  2. The server renders the page, including a _VIEWSTATE hidden field that contains encoded key-value pairs for the properties and values of every control on the page.
  3. The client enters information into the rendered HTML controls and then posts the page back to the server.
  4. The server initializes the page and then tracks the client's changes to control state. The server executes the business logic on the page and then renders the page. The server controls get rehydrated using the latest values stored in the _VIEWSTATE hidden field, which is updated to include the new, client-specified values and selections.
You manage view state using the StateBag class, which is a member of the System.Web.UI namespace.
The Page object provides access to a StateBag object through its ViewState property.

The StateBag class implements a number of interfaces, including the IDictionary and IEnumerable interfaces, which allow you to enumerate and modify the view state contents. Table 3 describes important members of the StateBag class.

Table 3: The StateBag Class Members
This method adds a new StateItem object to the StateBag object or updates an existing StateItem object value if it is already included in the StateBag class. The StateItem object represents a view state name-value pair.
This method removes an object from the StateBag object.
This property gets a collection of (enumerable) keys that represent the items in the StateBag object.
This property gets or sets the value of an object in the StateBag object.

You can add or modify view state items from the Web form code-behind file up until the Pre-Render stage of the page's lifecycle, which is just before the page starts rendering HTML. For example, you can append custom view state values that are distinct from any of the page controls:

protected override void OnPreRender(EventArgs e)
 // Store custom ViewState values
 ViewState("Key1") = "MyValue1";
 ViewState.Item("Key2") = "MyValue2";  // Alternate notation

In fact, you can add any object to view state, as long as it supports binary serialization. Serialization is the process by which binary data is converted into a stream of bytes in order to be saved to a storage medium. Serializable objects, such as the DataView object, implement the ISerializable interface.

Non-serializable objects, such as the ListItem object, do not implement this interface. As you can see, you can add serializable objects to view state easily:

// ViewState will store any serializable object
DataView dv;
ViewState.Add["Mydv", dv];

Retrieving objects from view state is just as simple:

if (!Page.IsPostBack)
 // Retrieve the DataView object from ViewState
 sqlDV = (DataView)ViewState["Mydv"];

Persisting View State Across Multiple Pages

In special cases, view state may persist values across multiple pages, not just across postbacks for the same page. Consider an application with two Web pages, where each page contains a TextBox server control named TextBox1.

If Page 1 submits to Page 2, then the TextBox control on Page 2 will pick up the view state for the Page 1 TextBox control. You can use this behavior to your advantage if you want to persist common information across multiple pages, as long as the Web application uses posting between pages, rather than hyperlinks.

For example, consider an application where every page contains a Label server control for persisting the client's login name. This is the design view for Page 1:

In the code-behind file, you would assign the login name to the Label control:

public class ViewState : System.Web.UI.Page
    protected System.Web.UI.WebControls.Label lblUserName;

    protected void Page_Load(object sender, EventArgs e)
        if (!Page.IsPostBack)
            // Assign Username to label (Username is hardcoded for demo purposes)
            lblUserName.Text = "DemoUser";

Then on subsequent Pages 2, 3, and so forth, you can automatically pick up the Label value from view state by doing just two things:
  1. Add a Label server control named "lblUserName".
  2. Add a variable declaration for the label in the code-behind file for the server control.
The only "coding" you need to do is to ensure that every page declares the server control variable:

protected System.Web.UI.WebControls.Label lblUserName;

The inverse behavior also applies: The view state will clear for all server controls that are not repeated between pages. Custom view state values will only persist for as long as the client continues to post back the same page.

Disabling View State

ASP.NET server controls have their view state enabled by default, but you can disable it for those controls that do not need to retain their values between postbacks. For example, DataGrid controls that are rehydrated on every postback donot need to retain their view state.

You can disable view state for a server control in two ways:
  • At design-time, by setting its EnableViewState attribute equal to "False":
  • At runtime, although make sure you do so the first time the page loads:

lblUserName.EnableViewState = false;

You can also disable view state for an entire page using the @ Page directive:

<%@ Page Language="C#" EnableViewState="false" CodeFile="Default.aspx.cs" Inherits="_Default" %>

Finally, you can disable view state for an entire application using the Web.config configuration file. To do so, simply modify the configuration element's enable ViewState attribute value:

Keep in mind that when view state is completely disabled, you will have to do a lot of work to manage state manually.


Hire Me

Follow me on Facebook

Follow me

Do you find this Blog helpful?

Follow by Email

About Me

My Photo
Expert Senior Software Developer

Microsoft Business Card