Filed under ASP.NET 4.0
I've never paid much attention to ViewState, but it's a pretty cool thing. It is a technique used by an ASP.NET Web page to persist changes across postbacks. Before posting back, all your data is stored in a hidden form field called __VIEWSTATE. That way when the page is rebuilt, your dropdown, textbox, label, etc data will still be there. You can read more in depth here, but it's just always worked and I haven't had concern for the huge payload that it can sometimes bring. Maybe that's why my bandwidth usage on my old e-commerce site is out of control!
Well now I'm paying attention and ASP.NET 4.0 gives us a new tool to help control ViewState, the ViewStateMode property. Say I have a dropdown where I select the quantity of a product that I want to buy. I then click "Add to Cart". Well, what happens when I click that button is that the page rebuilds itself and the code on my "Add to Cart" button is run. If I have ViewState turned off for my dropdown, when it comes time for run the "Add to Cart" code, the dropdown won't have any items in it! In fact, this happened to me today and I realized that I had ViewState turned off. By default, ViewStateMode is set to "Inherit", so all my child controls, including the quantity drop down wasn't saving it's values in ViewState. A simple change of the ViewStateMode property to "Enabled" fixes the problem and everything is happy.
See for yourself here in this sample project
Markup:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestViewState.Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Panel ID="pnlViewState" runat="server" ViewStateMode="Disabled">
<asp:DropDownList ID="DropDownList1" runat="server" ViewStateMode="Enabled" />
<asp:Button ID="Button1" runat="server" Text="Postback" OnClick="Button1_Click" />
</asp:Panel>
</div>
</form>
</body>
</html>
Code Behind:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace TestViewState
{
public partial class Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DropDownList1.Items.Add(new ListItem("1", "1"));
DropDownList1.Items.Add(new ListItem("2", "2"));
DropDownList1.Items.Add(new ListItem("3", "3"));
DropDownList1.Items.Add(new ListItem("4", "4"));
DropDownList1.SelectedIndex = 2;
}
}
protected void Button1_Click(object sender, EventArgs e)
{
DropDownList1.SelectedIndex = 3;
}
}
}
By enabling ViewStateMode on my dropdrown list, it persists the values so that they are available when posting back. To test this out, set ViewStateMode="Disabled" on the dropdown list and set a breakpoint on the Button1_Click event. Then run the project. Click the postback button and you'll see that DropDownList1 doesn't have anything in it! Change back to "Enabled" and you'll see everything works.
By setting the ViewState on individual controls, you can really cut down on your payload on each postback. This is a great addition in ASP.NET 4.0
Get the code for this project here:
TestViewState.zip (19.98 kb)
38dc9231-cb9e-435a-95ac-71987ad827a5|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04