Minimize a DropDownList's ViewState
Let's say you have a very large DropDownList with lots of values and text. We need to maintain ViewState in this DropDownList so that we can retrieve the selected value on a post back. Of course, this means that now the ViewState contains the data for every single value in the list, both values and text included. Even though the page itself may be fairly simple and lightweight, the result of having this simple DropDownList on the page is that the page size is quite large and the amount of data passed back and forth on a postback is very large as well.
If you have an efficient database, and/or if you are caching the data anyway, you might not mind re-loading the list items each time the page posts back to eliminate the need for the page itself to hold all of this ViewState data.
However, if you turn off ViewState on the DropDownList, you will notice that it now does not remember the selected value on post backs. The solution is very simple – just manually set the DropDownList after re-loading it to the value from the HTML form post.
To do this, first we disable ViewState on the DropDownList (EnableViewState="False"). Then, instead of a typical PageLoad() method like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
loadList();
// other stuff here
}
}
we would load the list every time the page posts back:
protected void Page_Load(object sender, EventArgs e)
{
loadList();
if (!IsPostBack)
{
// other stuff here
}
}
And, in that loadList() method, instead of simply doing this:
void loadList()
{
dlTest.DataSource = // get data from DB
dlTest.DataBind();
}
you also would check to see if it has a posted value:
void loadList()
{
dlTest.DataSource = // get data from DB
dlTest.DataBind();
string r = Request[dlTest.UniqueID];
if (r != null)
dlTest.SelectedValue = r;
}
That loads the DropDownList each time and ensures that the value set is what was posted back. Thus, the control will now "remember" the selected value on each postback, but without requiring any data stored in the ViewState at all.
It would also be easy to implement this logic in a control that inherits from DropDownList; say, a LightDropDownList. Techniques like this will of course work on other controls as well, such as a ListBox or a CheckedList.
With fast database connections and performance, as well as data caching, sometimes persisting data on the page is not the optimal way to go. Like always, there are different ways to skin a cat and sometimes simple little tweaks like this can have huge benefits on performance.
Update: See the comments for other options are that even easier/better. Also in the comments, Richard has provided a link to this excellent post on ViewState that I highly recommend checking out. It's long, but very informative and quite entertaining as well. Thanks for the great feedback.
Legacy Comments
Jd
2008-04-17 |
re: Minimize a DropDownList's ViewState There is even a simpler way if you understand the Page Life Cycle. Page_Load gets called AFTER your list's SelectedValue as been assigned during PostBack processing. But if you call loadList method in your Init event, then you don't have to worry about setting the selectedValue correctly. In ASP.NET 1.1, you will already have OnInit method, add your method called InitializePage() and call loadList and other relevant methods in it. protected override void OnInit(EventArgs e) { // // CODEGEN: This call is required by the ASP.NET Web Form Designer. // InitializeComponent(); InitializePage(); base.OnInit(e); } /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.Load += new System.EventHandler(this.Page_Load); this._btnSave.Click += new EventHandler(_btnSave_Click); } private void InitializePage() { loadList(); } Thanks, Jd |
Jeff
2008-04-17 |
re: Minimize a DropDownList's ViewState Ah yes, that makes perfect sense. Thank you, JD! |
Richard
2008-04-17 |
re: Minimize a DropDownList's ViewState There's an even better solution - leave the ViewState turned on, and load the list in the Init event of the list control. That way, you're loading the items before changes to ViewState are being tracked, so the items never get stored in ViewState. This has the same effect as declaring the items statically in the markup of your page. <asp:DropDownList ... OnInit="List_Init" ...> protected void List_Init(object sender, EventArgs e) { dlTest.DataSource = // get data from DB dlTest.DataBind(); } NB: You have to do this in the Init even of the control, not the page, as the Init event is raised from the bottom of the control tree up. http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx |
Jeff
2008-04-17 |
re: Minimize a DropDownList's ViewState Richard -- thanks for the great tip, and the great link !! |
Jd
2008-04-23 |
re: Minimize a DropDownList's ViewState Those 'Truly Understanding' pages are excellent. And I think you can do it in Page's OnInit, it would still work. This is because those Lifecycle events runs one after the other. Actually, Page derives from Control and those On* events are part of all the controls as well as the page itself. |
Dave Reed
2008-04-28 |
re: Minimize a DropDownList's ViewState @ jd -- no, Richard is right, you must do it from the control's init method. When Page.OnInit occurs, the child controls have already init'd and are tracking viewstate already. Init occurs from the bottom of the tree, up, not "one after the other". |
bhart
2008-11-10 |
re: Minimize a DropDownList's ViewState thanks for the tip it helps me a lot |
jk
2009-01-05 |
re: Minimize a DropDownList's ViewState hey, i tried to implement it in a particular scenario, it didn't help me though. The scenario is : on a .ascx page, The drop down's selected value is coming from database. Now i change the value to some other value. There is a control post back on .ascx page. Ideally, after post back the value should be the value from DB. But it loads with the value i changed to. |