My ASP.Net class is just getting underway and we're getting into the topic of state management. We briefly covered the intrinsic Application and Session objects as State repositories, and ViewState was brought into the conversation. ViewState plays an important role in maintaining control values (a.k.a state) between postbacks of your ASP.Net pages. Let's learn a bit more about ViewState by decoding it in a simple web application.
I added a textbox, a button, and a datagrid to a webform and added the following code to the page (be sure to make the textbox TextMode="MultiLine" for ease of reading):
private void Page_Load(object sender, System.EventArgs e)
{
string cn = "server=server;database=northwind;uid=sa;pwd=password;";
string sql = "SELECT TOP 5 * FROM Customers";
DataGrid1.DataSource = SqlHelper.ExecuteDataset( cn, CommandType.Text, sql );
DataGrid1.DataBind();
}
//writes the decoded viewstate to the textbox
protected void decodeViewState()
{
string strV = HttpContext.Current.Request[ "__VIEWSTATE" ].ToString();
byte[] arrBytes = System.Convert.FromBase64String( strV );
ASCIIEncoding enc= new ASCIIEncoding();
char[] charArray = new char[ enc.GetCharCount( arrBytes, 0, arrBytes.Length ) ];
enc.GetDecoder().GetChars( arrBytes, 0, arrBytes.Length,charArray, 0 );
foreach( char c in charArray )
{
Textbox1.Text += c;
}
}
private void Button1_Click(object sender, System.EventArgs e)
{
decodeViewState();
}
I should note I also added a reference to the MSFT Data Access Application block (that's where the SqlHelper class originates) and set the following using statements for convenience:
using Microsoft.ApplicationBlocks.Data;
using System.IO;
using System.Text;
When this page loads, our datagrid displays the first 5 rows from the Customers table in the NorthWind database. If we view the generated HTML source for this page, we can see the viewstate stored in a hidden HTML input tag; the HTML will look something like the following (I deleted a lot of the value since I think you get the idea):
INPUT type=hidden value=dDwxOTI0OTQwNjAwO3Q8O2w8aTwxPjs+iAzNCA2Nzs+Pjs+Ozs+Oz4+Oz4+Oz4+Oz4+Oz4+Oz4W9zriiE/kuozP9dKgDteQYb9P5w== name=__VIEWSTATE
If we press our Button1 (and invoke the decodeViewState method), our textbox will display the decoded version of the viewstate (I chose to NOT delete any of the decoded text so you could see the whole thing):
| t<1924940600;t<;l;>;l;>;l;l;i<5>;i<1>;i<5>;>>;>;;;;;;;;;@0<@0 ;l;>>;;;;>;@0;l;>>;;;;>;@0;l;>>;;;;>;@0;l;>>;;;;>;@0;l ;>>;;;;>;@0;l;>>;;;;>;@0;l;>>;;;;>;@0;l;>>;;;;>;@0;l;>>;;;;>;@0;l;>>;;;;>;@0;l;>>;;;;>;>;>;l;>;l;i<2>;i<3>;i<4>;i<5>;>;l;i<1>;i<2>;i<3>;i<4>;i<5>;i<6>;i<7>;i<8>;i<9>;i<10>;>;l;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l< \;;>>;>;;>;t ;l<12209;>>;>;;>;t ;l>;>;;>;t;l<030-0074321;>>;>;;>;t ;l<030-0076545;>>;>;;>;>>;t<;l;i<1>;i<2>;i<3>;i<4>;i<5>;i<6>;i<7>;i<8>;i<9>;i<10>;>;l;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l< \;;>>;>;;>;t ;l<05021;>>;>;;>;t ;l>;>;;>;t;l<(5) 555-4729;>>;>;;>;t ;l<(5) 555-3745;>>;>;;>;>>;t<;l;i<1>;i<2>;i<3>;i<4>;i<5>;i<6>;i<7>;i<8>;i<9>;i<10>;>;l;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l< \;;>>;>;;>;t ;l<05023;>>;>;;>;t ;l>;>;;>;t;l<(5) 555-3932;>>;>;;>;t ;l< \;;>>;>;;>;>>;t<;l;i<1>;i<2>;i<3>;i<4>;i<5>;i<6>;i<7>;i<8>;i<9>;i<10>;>;l;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l<120 Hanover Sq.;>>;>;;>;t ;l>;>;;>;t;l< \;;>>;>;;>;t ;l>;>;;>;t;l>;>;;>;t;l<(171) 555-7788;>>;>;;>;t ;l<(171) 555-6750;>>;>;;>;>>;t<;l;i<1>;i<2>;i<3>;i<4>;i<5>;i<6>;i<7>;i<8>;i<9>;i<10>;>;l;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l>;>;;>;t;l< \;;>>;>;;>;t ;l>;>;;>;t;l>;>;;>;t;l<0921-12 34 65;>>;>;;>;t ;l<0921-12 34 67;>>;>;;>;>>;>>;>>;>>;>>;>?:??O?????????a?O? |
As we see, the ViewState is simply base64 encoded text; some of it is hard to read even after the unecoding with all the angled brackets and semi-colons, but the data is all apparent. The ASP.Net plumbing uses this to track state data (such as location in a paged datagrid, make datagrid rows available in PostBack event handling, etc.). You will may never need to decode ViewState like I've done, but it is good to understand that there is no magic to it. It's just some encoded text storing properties and data related to the controls on your page. I should point out that you can add your own data to ViewState (as an alternative to Session state -- but with a different set of pros and cons); you can also encrypt ViewState using the machine.config file on the server. These are both topics for another blog.
If you can't wait of another blog on ViewState, here are some additional resources . . .
Back in June, Chris Hale did an overview of ViewState for WeProgram.Net. Those materials are available here (at the bottom of the page). For a solid MSFT treatment of the subject, including how to tune or disable ViewState to improve performance, check out this link: http://msdn.microsoft.com/netframework/downloads/samples/default.aspx?pull=/library/en-us/dnaspnet/html/asp11222001.asp.
Happy .Netting!