About Links Archives Search Feed Albums of Note

ASP.NET, Part 7: A New Viewstate Opt-in Model

Welcome to part 7 of my tour through ASP.NET 4.0 [http://blog.hmobius.com/post/2010/02/09/ASPNET-40-Cometh.aspx]. Today we’re going to look at what in hindsight was one of the larger design mistakes that Microsoft made when creating ASP.NET – The View State Opt-Out Model for Web Forms – and how they’ve approached a solution.

[Updated Feb 24: Added link to more in-depth tutorial on View State at end of article].

HTTP is Stateless One of the first things you learn as a web developer is that HTTP is a stateless protocol. Requests sent over HTTP are independent of any that have gone before and retain no information about the user sending them or the state of the page (where the state is defined as the property values of the controls that make up the page’s control hierarchy.)

The issue then is how to retain such information between requests and, more significantly in this discussion, between postbacks on the same page. The standard solutions are to

Enter View State Back in 2000, View State was created by Microsoft so we fledgling web developers didn’t have to worry about persisting this state information onto the next page. It was just another great feature whereby this information was base64-encoded on the server and stored in a hidden form element on the page named __VIEWSTATE. When the page was posted back, View State would be sent back with it and hey presto, instant state.

Ten years later, the benefit of using View State is still apparent but, as any ASP.NET MVC developer will tell you, it is not a necessary part of a web page. (To whit, MVC doesn’t use View State at all.) There are two main issues with View State

  1. All pages take a performance hit as the server must deal with decrypting, reading, rebuilding and re-encrypting view state with each post back of a page to the server. The exact process is described here [http://msdn.microsoft.com/en-gb/library/ms972976.aspx]. Pages which dynamically add controls to the page may also cause exceptions when the server cannot match the control tree in the view state to that on the page. 2. The value in the __VIEWSTATE hidden form field can grow quite large quite quickly. Without you realising it, it could add several dozen kilobytes to your page resulting in slower transmission times to your users and back to the server when it is sent back to the server in the HTTP POST headers.

The solution to both these problems for Web Forms developers is to make sure that only the controls which need their state persisted across postbacks are included in View State and herein lies the main problem with View State that is being addressed in ASP.NET 4.0.

Opt-Out Mode vs. Opt-In Mode From ASP.NET v1.0 to v3.5 SP1, there has only been an opt-out model for View State on a Web Forms page. This means that View State is switched on for every control on every page by default, unless you opt to disable it by setting the Page or Control’s EnableViewState property to false. The problem is that once EnableViewState is set to false for a Page for example, it is also set to false for every child control of that page, and there is no facility to override that further down the tree and have View State switched on for a control on that page.

Consider the scenario where I have several dozen form controls on a page and wish to maintain view state for just one DropDownList. I cannot set EnableViewState to false for the whole Page and then set it to True for the DropDownList. Instead I must leave EnableViewState set to true on the page and explicitly set it to false for every other control on the page as long as it isn’t a parent control for the DropDownList.  

Which isn’t too great.

Fortunately, Microsoft has heeded our cries and added an opt-in model for View State in ASP.NET 4.0. Addressing the same scenario using the opt-in model, I can indeed switch off View State for the whole Page and then re-enable it explicitly on the one DropDownList I need to maintain state for. However, I do it with a new property called ViewStateMode rather than EnableViewState.

Introducing ViewStateMode The switch between opt-out and opt-in models is made using the new ViewStateMode property. This has three possible values.

It can be set both code-behind and declaratively in markup as an attribute of a control or of the @Page directive.

<%@Page … ViewStateMode=“Disabled” %>

Let’s take an example. In the code below, we have a normal WebForms page with EnableViewState set to true by default.

<%@ Page Language=“C#” AutoEventWireup=“true” CodeFile=“ViewStateDemo.aspx.cs” Inherits=“ViewStateDemo” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> View State Demo

In the code-behind for this page, we re-set the Text properties for the two Labels and Button if the page has not posted back.

protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { lblOne.Text = “My set value”; lblTwo.Text = “My set value”; btnGo.Text = “View State Is On”; } }

When it loads, the page will load and the new Text values displayed. With View State enabled, those text values will stay the same when you click the button and post the page back to the server.

Now set ViewStateMode to Disabled for on the plhOuter PlaceHolder control.

Now when you run the page and click the button, you’ll see that the two Labels lose their value as it is not persisted in View State. However, the Button control, which is outside the PlaceHolder still uses View State.

So far, this is nothing new. We could replace the ViewStateMode property with EnableViewState set to false and get the same result. However, we could not then also set ViewStateMode to Enabled on the pnlInner Panel control and restore ViewState to the lblTwo Label control.

Now run the page and click the button again to confirm that View State is now on for lblTwo. If you did try and replace ViewStateMode property with EnableViewState set to false on the plhOuter control now and hit the button, you’ll see that EnableViewState overrides ViewStateMode and produces the results in the screenshot above rather than the one below.

The ViewStateMode property can be set on any control or on the Page itself and not just invisible container controls as we’ve seen so far. Move ViewStateMode=”Disabled” from the plhOuter control to the @Page directive.

<%@ Page ViewStateMode=“Disabled” Language=“C#” AutoEventWireup=“true” CodeFile=“ViewStateDemo.aspx.cs” Inherits=“ViewStateDemo” %>

Run the page again and you’ll see how the Button control now also loses state across a post back while lblTwo continues to retain it as ViewStateMode is still enabled on it.

Remember : View State is not Control State While this demo adequately shows you how ViewStateMode is inherited through the Control hierarchy of a page, it would have failed had I tried to use TextBox or DropDownList controls instead of Labels with the code-behind setting their selected value or text. The DropDownList would have retained its SelectedIndex and the TextBox its Text whether View State was enabled or not because those particular properties are stored in control state. Control state is designed for storing a control’s essential data (such as a TextBox’s text) that must be available on postback to enable the control to function even when view state has been disabled. Thus control state is always maintained even if EnableViewState is set to false and ViewStateMode is set to Disabled.

What We’ve Learnt In today’s episode, we’ve seen that ASP.NET 4.0 presents a new opt-in mode for View State on a page via the new ViewStateMode property. However, we’ve also seen that setting the EnableViewState property to false will disable View State for any child control or page regardless of whether one has had ViewStateMode set to Enabled on it. Thus for any control’s state to be saved in a page’s View State, the following must be true.

We also noted that the setting of ViewStateMode has no influence over the workings of a Control’s Control State.

For a really good, in-depth look at how View State works, you can look at both of these:

Happy Coding!

Posted on February 24, 2010   #Geek Stuff  

← Next post    ·    Previous post →