Introduction
The ASP.NET Web Forms model strives to encapsulate the lower level complexities involved in building a web application. Features like server-side event handlers, the page lifecycle, and view state effectively blur the line between the client and the server, simplify state management, and free the developer from worrying about HTTP
, requests and responses, and similar matters. While these facets of the Web Forms model allow for rapid application development and make ASP.NET more accessible to developers with a web application background, their behavior can impact your website's behavior and performance.
View state is perhaps the most important - yet most misunderstood - feature of the Web Forms model. In a nutshell, view state is a technique that automatically persists programmatic changes to the Web controls on a page. By default, this state is serialized into a base-64 encoded string and included as a hidden <input>
field in the Web Form. On postback, this state information is returned to the server as part of the POST request, at which point the server can deserialize it and reapply the persisted state to the controls in the control hierarchy. (If this last paragraph made crystal clear sense, great! If not, consider reading my article, Understanding ASP.NET View State, and Dave Reed's article, ViewStateMode in ASP.NET 4, before continuing.)
One potential issue with view state is that it can greatly bloat the size of your web pages. Each new version of ASP.NET seems to include new techniques for managing view state's footprint. ASP.NET 4 adds a new property to all Web controls, ViewStateMode
, which allows developers to disable view state for a page by default and then selectively enable it for specific controls. This article reviews existing view state-related properties and then delves into the new ViewStateMode
property. Read on to learn more!
View state enables programmatic changes to Web controls in a Web Form to be persisted across postbacks. For example, consider the common scenario of a web page with a Label Web control whose
Text
property is set programmatically in the Page_Load
event handler using code like the following:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load |
Chances are, we've all written code like the above at one point or another. In the above case, the Label's Text
property value is stored to the page's view state. If there is a Button on the page or some other control that causes a postback, the above code will not run (because it only executes when Page.IsPostBack
is False), however the Label's Text
property value is remembered from when it was set previously thanks to view state.
View state can be a great time saver as it handles a common state maintenance scenario so that developer is free to focus on other tasks. However, view state adds to the rendered size of the page and affects how much data is sent to the server on postback. Consequently, as a page's view state grows is can impact the user's experience, making the page slower and the response time more sluggish.
To help manage the view state's footprint, you can selectively enable or disable view state on a control-by-control basis; this functionality has been around since ASP.NET's initial release. Specifically, use a control's EnableViewState
property to indicate whether it (and its children controls) should save their view state. The EnableViewState
property can be set for a specific Web control at the page level in the @Page
directive, or for the entire application in the Web.config
file.
When ASP.NET was initially released, view state was the only place a Web control could use to persist state information across postbacks. This included both important state information, like a DataGrid's EditItemIndex
property, and less important state information, like a Label's background color . Unfortunately, page developers who wanted to mitigate their view state size could not say, "Only store the important stuff in view state." To remedy this, ASP.NET 2.0 introduced the concept of control state. A control developer building a Web control can optionally use control state to place important state information that is required for the control to function properly. Behind the scenes, control state is serialized to the hidden view state form field, however cannot be disabled by a page developer.
Control state is not something a page developer has to concern herself about. Instead, it's more important for control developers. Because control state is persisted in the same manner as view state - namely, through the same hidden form field - even if you disable view state for the entire page (or website) you may find that you have a sizable chunk of view state data in the rendered page. In other words, control state allows Web controls to define some state that cannot be disabled by a page developer. (For more information on using control state, refer to Phil Haack's excellent article, Gain Control Of Your Control State.)
Introducing the ViewStateMode
Property
The existing EnableViewState
property allows for page developers to mitigate view state's size by either turning off view state altogether or by having view state enabled by default and then turning it off on a control-by-control basis. ASP.NET 4 still allows this pattern, but introduces the opposite approach, as well, using the new ViewStateMode
property. In a nutshell, with ASP.NET 4 you can instead disable view state by default and then pick and choose which controls on the page should use view state.
The ViewStateMode
property can be set at the page level in the @Page
directive or for individual controls, and can accept one of the following three values:
Inherit
- causes the control to inherit the value of theViewStateMode
property from its parent (the default),Enabled
- enables view state for the control even if the parent control has its view state disabled, orDisabled
- disables view state for the control even if the parent control has its view state enabled.
@Page
directive's ViewStateMode
property to Disabled
and the control of interest's ViewStateMode
property to Enabled
, like so:
<%@ Page ... ViewStateMode="Disabled" %> |
Because the page's view state is disabled by default, Label1
will not save its view state (ditto for any other controls on the page that do not explicitly enable view state). However, Label2
will save view state because it overrides the default behavior by virtue of setting its ViewStateMode
to Enabled
.
If EnableViewState and ViewStateMode Got In A Fight Who Would Win? |
---|
With the addition of the ViewStateMode property, Web controls now have two view state-related properties: ViewStateMode and EnableViewState . A natural question is, "How do these work when set to conflicting values?" For example, what happens if EnableViewState is set to True but ViewStateMode is set to Disabled , or EnableViewState is set to False but ViewStateMode is set to Enabled ? The answer is that if EnableViewState is True, then the ViewStateMode setting applies; however, if EnableViewState is False then the control will not save its view state, regardless of the ViewStateMode setting. |
Examples of Using ViewStateMode
The download available at the end of this article illustrates how the ViewStateMode
property works. The demo includes three separate web pages:
- One that uses the default, out of the box behavior (view state enabled),
- One that disables view state for the entire page, and
- One that uses the
ViewStateMode
property to disable view state for the page by default, but to enable it for a specific control on the page.
For the page that uses the default view state behavior (having it enabled for all controls on the page), the demo would work like you expect it to. The style settings of the three Label controls remain across postbacks. The screen shot below shows this page after postback. Note the view state size - 280 bytes.
The second demo has view state disabled by virtue of setting the @Page
directive's EnableViewState
property to False. As a consequence, none of the controls on the page save view state information. On postback, the style settings applied programmatically to the last two Labels are lost, as the following screen show shows. The first Label's style settings remain because they were made declaratively, and therefore don't need to be (and aren't) stored in view state. Note the reduced size of view state in this example - 68 bytes instead of 280. (This also illustrates how that even when view state is disabled there is still a small amount of view state emitted to the page, and there could be more if the page included controls that used control state.)
The third and final demo shows how to disable view state by default, but then selectively enable it on a control-by-control basis. In particular, in this demo the @Page
directive has its ViewStateMode
property set to Disabled
. The second Label overrides this default behavior by setting its ViewStateMode
property set to Enabled
, whereas the third Label does not set its ViewStateMode
property and therefore inherits its parent's ViewStateMode
setting (Disabled
). After postback, the style information in the second Label is maintained, as it was saved in view state; however, the third Label has lost its styling. As you would expect, the view state footprint for this demo is less than the "all view state enabled" demo but more than the "no view state enabled" demo - specifically, view state takes up 216 bytes.
Conclusion
ASP.NET 4 offers developers finer control over the view state emitted by their Web Forms through a new property, ViewStateMode
. Using the ViewStateMode
property you can enable or disable view state for a particular control and its children controls. What's more, you can have a child control override its parent control's ViewStateMode
setting, something that wasn't possible before. With this new functionality you can disable view state for an entire page and then selectively enable for those controls that need it. Check out the demo available for download at the end of this article to see this new property in action.