Using ViewState to Store State in the Page Output


Using ViewState to Store State in the Page Output

As stated earlier in the section on session state, Web application communication takes place over HTTP, a stateless protocol. The ASP.NET session state feature circumvents the stateless nature of HTTP by storing its SessionID in an HTTP cookie or embedding it within the URL of the page. This shared session key is then used to associate data stored on the server with the browser making the request.

In some cases, it isn’t necessary or desirable to require session state, and a common technique that many developers have used in the past is to store data in hidden form fields like this: <input type="hidden" value="some value here"/>. When the client submits the page and causes either an HTTP POST or GET request to the server, this data, along with other input form data, is sent to the server in either the POST body or the query string.

ASP.NET has taken this concept of hidden input form fields and utilized them for maintaining state for pages that participate in postback. (All ASP.NET pages that use <form runat="server"/> send the contents of the form back to the same page. Additionally, the action attribute of form is ignored when the form is marked with runat="server".) This feature is known as view state; data is stored in a special hidden <input type="hidden" name="__VIEWSTATE"/> form element. The data stored in the value attribute of the __VIEWSTATE form element consists of a base-64 encoded string that contains all the serialized ViewState data for the current page plus a MAC (Message Authentication Code). When the page is posted back to the server, the ASP.NET page framework deserializes the data in __VIEWSTATE and automatically repopulates the ViewState state bag. Thus data added to the view state is available when the page is posted back again. View state is very useful for building complex server controls since data not usually sent as a form element can be stored in the view state and retrieved when the page is posted back. (For more details on the inner workings of view state, I highly recommend you take a look at Chapter 7 of Developing Microsoft ASP.NET Server Controls and Components, written by Nikhil Kothari and Vandana Datye and published by Microsoft Press.)

Note

A MAC is a key-dependent, one-way hash. A MAC is used to verify ViewState data by recomputing the MAC on post back and comparing it to the MAC stored in __VIEWSTATE. If the MACs match, the data in __VIEWSTATE is valid. If they do not match, the ViewState data is invalid and an exception is thrown.

Programming ViewState

ViewState data is accessible in much the same way that Session data is; both use a key to set or retrieve data. However, unlike Session, ViewState data is available only in pages that utilize <form runat="server"/>, which causes the page to perform a postback. The data types that can be stored in ViewState are limited to Int32, Boolean, String, Unit, and Color. Data types other than these incur significant overhead and must first either be converted to a string or be serialized using the same binary serializer used by session state.

The view state can be extremely useful in cases in which there is a costly piece of data to fetch that is necessary for the duration of the page (where duration of the page is equal to the first request and all postbacks). A great example of this is in the source code for the ASP.NET Forums (www.asp.net/forums). One of the controls used frequently within the Forums is a server control used for paging data. This server control (Paging.cs) allows the user to page through multiple records of data in SQL Server (as opposed to paging through the data in ASP.NET). One of the paging control’s tasks is to keep track of the total number of available records. Using this number and the requested page size, the control can calculate the total number of pages available. The total records available are not computed on each request—instead, this data is fetched once and stored in view state, alleviating the stress on the server from making multiple requests to the database for the same information.

Below is a code snippet from the Paging.cs file that demonstrates this technique—the full source is available as part of the ASP.NET Forums downloadable from www.asp.net.

/// <summary>
/// TotalRecords available
/// </summary>
public int TotalRecords {
get {
// The total records available is stuffed into
// ViewState so that we don’t pay the lookup cost
// across postbacks.
if (ViewState["totalRecords"] == null)
return defaultTotalRecords; // 0

return Convert.ToInt32(ViewState["totalRecords"].ToString());
}
set {
// Recalculate the total number of pages in case page size changed
TotalPages = CalculateTotalPages(value, PageSize);

// set the ViewState
ViewState["totalRecords"] = value;
}
}

ViewState’s Liability

Using ViewState does have a liability: it increases the total size of the page that must be created. Although it doesn’t affect the UI generated by the page, the HTML payload can dramatically increase depending upon how much view state is used by the page. We recommend that you disable ViewState for page or controls that don’t require it.

Tip

The view state can be disabled in a page by using <%@ Page EnableViewState="false" %>, or in a control by specifying Page.EnableViewState="false" on the server control.

Without disabling view state, the following code sample demonstrates using the DataGrid server control bound to a DataSet to serialize the XML document BookData.xml to base64 in an XML attribute value:

Code Listing 5-5: Serializetobase64.aspx

start example
 <%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>

<script runat="server">

public void Page_Load (Object sender, EventArgs e) {

// Load some data
DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath("BookData.xml"));

// Now databind to the datagrid
DataGrid1.DataSource = ds;
DataGrid1.DataBind();

}
</script>
<form runat="server">
<asp:Button runat="server" Text="PostBack" />
</form>
<asp:DataGrid runat="server" />
end example

When this page is requested and the HTML source is viewed, the value for __VIEWSTATE contains this:

<input type="hidden” name="__VIEWSTATE”  value="dDwxMzg3MzYyMzg7dDw7bDxpPDI+Oz47bDx0PEAwPHA8cDxsPERhdGFLZXlzO18hSXRlbUN vdW5[ …30 lines removed…]z47dDxwPHA8bDxUZXh0Oz47bDxQYXJpczs+Pjs+Ozs+O3Q8cDxwPGw8V GV4dDs+O2w 8Jm5ic3BcOzs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8RnJhbmNlOz4+Oz47Oz47Pj47Pj47 Pj47Pj47Phd0PzY b9Lz7N2ZqMReiGAMMnwyz” />

In this case, we’re not using a view state, so we should disable it by adding an EnableViewState attribute to DataGrid:

<asp:DataGrid  runat="server" EnableViewState="false" /> 

Now when this page is requested, the value for __VIEWSTATE is more reasonable:

<input type="hidden” name="__VIEWSTATE” value="dDwxMzg3MzYyMzg7Oz6TQ21xg8KTWseIQ341mOOdKXguIw==“ /> 

View state is a powerful technique for managing state for pages that participate in post back. However, you need to be aware that view state has an associated cost that can easily increase the size of your page output, as demonstrated in this code sample.




Microsoft ASP. NET Coding Strategies with the Microsoft ASP. NET Team
Microsoft ASP.NET Coding Strategies with the Microsoft ASP.NET Team (Pro-Developer)
ISBN: 073561900X
EAN: 2147483647
Year: 2005
Pages: 144

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net