Click here to Skip to main content
Click here to Skip to main content

DataGrid's ViewState optimization

By , 11 Apr 2005
Rate this:
Please Sign up or sign in to vote.

Introduction

This article shows you how to reduce size of ViewState data generated by DataGrid control, while maintaining all DataGrid's functionality like selecting items or paging.

I assume that you know what it's and how to use ViewState. If not, please first learn about them, e.g. read article Taking a Bite Out of ASP.NET ViewState. In that article you also find general information about reducing size of ViewState.

Background

When I started to learn and use ASP.NET in practice, one of my problems was ViewState - usually it's too large! Usually I can reduce its size, by disabling it for selected controls or for whole page. Unfortunately, when I disable VS for control, sometime I lost some of its functionality. This is true for DataGrid - when you disable ViewState, you'll lose advanced functions like selecting items or paging. On the other side, ViewState generated by DataGrid is usually very large - it grows with every added row and column.

In last two weeks I decided to finally solve this problem. I assumed that DataGrid store copy of my DataTable in ViewState, or my data is stored column-by-column by BoundColumn objects. As I found later, it was a wrong assumption.

First I displayed the whole tree of controls used to display my page. First surprise - DataGrid uses internally other controls to display is contents. Here is sample control tree for 2x2 DataGrid:

  • DataGrid
    • DataGridTable
      • DataGridItem
        • TableCell
        • TableCell
      • DataGridItem
        • TableCell
        • TableCell

DataGridTable is the class derived from System.Web.UI.WebControls.Table. DataGridItem objects represents rows, and TableCell represents cells of DataGrid.

Next I decompiled .NET binaries using Reflector [^] and I browsed code of DataGrid, BaseDataList (its base class), BoundColumn, and DataGridColumn classes. Unfortunately I found nothing that may help me solve my problem.

In this point, I decided to try to decode and analyze contents of my ViewState. I used ViewState Decoder [^] for this. When I displayed my ViewState's data, its structure looked familiar for me. After wards, I found that - it's similar to control tree on my page! And I think - what if I disable ViewState for each row of DataGrid? I checked this and... Eureka! That's it!

How to reduce size of DataGrid's ViewState - summary

Disable ViewState

If you can, disable the ViewState for whole DataGrid (set property EnableViewState to false), or better for whole page. If you need advanced DataGrid's functionality like selecting items or paging, you can't use this method. In this case you should use methods listed below.

Disable columns autogeneration

Set property AutoGenerateColumns to false, and create columns manually using Property Builder for DataGrid control. When columns are generated automatically, information about them is stored in the ViewState.

Disable ViewState for each DataGrid's row

This is the best method, because copy of displayed data is stored in ViewState as values of TableCell.Text property. When you disable that, DataGrid ViewState's size will be constant and don't increase when you display more rows. You can use the following code for this:

private void DisableViewState(DataGrid dg)
{
    foreach (DataGridItem dgi in dg.Items)
    {
        dgi.EnableViewState = false;
    }
}

private void Page_Load(object sender, System.EventArgs e)
{
    MyDataGrid.DataSource = GetData();
    MyDataGrid.DataBind();
    DisableViewState(MyDataGrid);
}

Store required identifiers in ViewState as string[] array

When you display data for user, you need to store identifiers of displayed data. You can store them in hidden DataGrid's column, but this is not optimal - your ids will be stored as DataGridItem/TableCell/string tree (you also need to change code from previous method to disable ViewState only for selected columns). Better solution is to store ids in ViewState as string[] array. Note: int[] array may seem to be more appropriate, but not: data generated by LosFormatter class is more compact for string[] array than for int[] array. This is caused by fact that class LosFormatter is optimized only for string[] arrays.

Example: You have array of three ids: 1, 2, 3. If you store them in ViewState as string[], you get:

@<1;2;3;>

When you store them as int[], you get:

@System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, 
                  PublicKeyToken=b77a5c561934e089<i<1>;i<2>;i<3>;>

If you store more int[] arrays in ViewState, all except first will be stored as following:

@50<i<1>;i<2>;i<3>;>

Alternatively you can store your ids in ArrayList - below are data generated from ArrayList for values stored as string, and as int:

l<1;2;3;>
l<i<1>;i<2>;i<3>;>

Here is an example code that creates and stores array with ids in ViewState:

DataTable dt = GetData();
MyDataGrid.DataSource = dt;
MyDataGrid.DataBind();

string[] ids = new string[dt.Rows.Count];
for (int n=0; n<dt.Rows.Count; ++n)
    ids[n] = dt.Rows[n]["id"].ToString();
ViewState["ids"] = ids;

When you need to retrieve id of displayed data, use following code:

int index = MyDataGrid.SelectedIndex;
string[] ids = (string[])ViewState["ids"];
int myID = Convert.ToInt32(ids[index]);

Statistics

I created page that display a 10*10 table. Each cell contains a three digit number. Below are results of my tests:

VS - ViewState, CA - columns autogeneration.

Description ViewState size
VS enabled, CA enabled 6032
VS enabled, CA disabled 5028
VS disabled for rows, CA disabled 236
VS disabled for cells in all column except first, CA disabled 948
VS disabled for rows, CA disabled, ids stored in VS as int[] 476
VS disabled for rows, CA disabled, ids stored in VS as string[] 316
VS disabled for rows, CA disabled, ids stored in VS as ints in ArrayList 356
VS disabled for rows, CA disabled, ids stored in VS as strings in ArrayList 316

As you see ViewState, size is reduced from 6032 to 316 bytes. We saved 5716 bytes, and now ViewState contains only 5.2% of the beginning data!

Points of Interest

I worked on primary method covered in this article (disable ViewState for each DataGrid's row) for almost two weeks. It's true that simplest solutions are most difficult to find.

I found also that, data stored in ViewState could be optimized. This can be done if you know how LosFormatter works. Other method is to implement own class to replace LosFormatter and this is the subject for other article.

History

  • 4/11/2005

    First version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Daniel Fruzynski
Web Developer
Germany Germany
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 PinmemberDaniel Cohen Gindi5-Mar-13 8:30 
GeneralWhat will be happen the if we write the code in ItemDataBound event of that grid Pinmemberhasan.rounak5-Jun-11 21:21 
Questionhurrrry..,data in "GridView" invisible in post back,need the proper code for "viewstate" implementation Pinmembersumans432428-Oct-09 21:43 
GeneralWhats the use of this when my data is lost on a post back Pinmemberbhat12343-Feb-06 23:56 
I did as whatever was said and on post back my data is lost, so whats the use of such a datagrid
GeneralRe: Whats the use of this when my data is lost on a post back Pinmemberfroman11815-Feb-06 7:52 
GeneralTry to put 2 or more DataGrids with paging enabled! Pinmembercupo11-Oct-05 12:01 
GeneralRe: Try to put 2 or more DataGrids with paging enabled! PinmemberDaniel Fruzynski12-Oct-05 7:38 
GeneralRe: Try to put 2 or more DataGrids with paging enabled! Pinmembercupo12-Oct-05 12:31 
GeneralRe: Try to put 2 or more DataGrids with paging enabled! PinmemberDaniel Fruzynski13-Oct-05 7:34 
GeneralRe: Try to put 2 or more DataGrids with paging enabled! Pinmembercupo13-Oct-05 13:16 
GeneralRe: Try to put 2 or more DataGrids with paging enabled! PinmemberDaniel Fruzynski14-Oct-05 22:17 
GeneralViewstate Optimization Pinmemberbarani_7624-Jul-05 6:11 
GeneralGreat one! PinmemberAbishek Bellamkonda20-Apr-05 21:51 
GeneralI love an unintentional Pun! PinsussAnonymous21-Apr-05 4:13 
GeneralRe: I love an unintentional Pun! PinmemberAbishek Bellamkonda21-Apr-05 13:25 
GeneralRe: I love an unintentional Pun! PinmemberXagyg3-Jun-08 4:40 
GeneralRe: Great one! PinsussBugsbuddy21-Apr-05 21:56 
GeneralRe: Great one! PinmemberAbishek Bellamkonda23-Apr-05 12:34 
QuestionHow different is this approach? PinmemberSathish Kumar K11-Apr-05 17:13 
AnswerRe: How different is this approach? PinmemberRobert V11-Apr-05 18:26 
GeneralRe: How different is this approach? PinmemberSathish Kumar K13-Apr-05 6:19 
GeneralRe: How different is this approach? Pinmemberspvarapu29-Sep-05 21:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140415.2 | Last Updated 11 Apr 2005
Article Copyright 2005 by Daniel Fruzynski
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid