WEBSITE

ASP.NET State Management : The View State of a Page (part 1) - The StateBag Class, Common Issues with View State

5/15/2013 1:48:33 AM
ASP.NET pages supply the ViewState property to let applications build a call context and retain values across two successive requests for the same page. The view state represents the state of the page when it was last processed on the server. The state is persisted—usually, but not necessarily, on the client side—and is restored before the page request is processed.

By default, the view state is maintained as a hidden field added to the page. As such, it travels back and forth with the page itself. Although it is sent to the client, the view state does not represent, nor does it contain, any information specifically aimed at the client. The information stored in the view state is pertinent only to the page and some of its child controls and is not consumed in any way by the browser.

Using the view state has advantages and disadvantages that you might want to carefully balance prior to making your state management decision. First, the view state does not require any server resources and is simple to implement and use. Because it’s a physical part of the page, it’s fast to retrieve and use. This last point, that in some respects is a strong one, turns into a considerable weakness as soon as you consider the page performance from a wider perspective.

Because the view state is packed with the page, it inevitably charges the HTML code transferred over HTTP with a few extra kilobytes of data—useless data, moreover, from the browser’s perspective. A complex real-world page, especially if it does not even attempt to optimize and restrict the use of the view state, can easily find 20 KB of extra stuff packed in the HTML code sent out to the browser.

In summary, the view state is one of the most important features of ASP.NET, not so much because of its technical relevance but because it allows you to benefit from most of the magic of the Web Forms model. Used without strict criteria, though, the view state can easily become a burden for pages.

1. The StateBag Class

The StateBag class is the class behind the view state that manages the information that ASP.NET pages and controls want to persist across successive posts of the same page instance. The class works like a dictionary and, in addition, implements the IStateManager interface. The Page and Control base classes expose the view state through the ViewState property. So you can add or remove items from the StateBag class as you would with any dictionary object, as the following code demonstrates:

ViewState["FontSize"] = value;

You should start writing to the view state only after the Init event fires for the page request. You can read from the view state during any stage of the page life cycle, but not after the page enters rendering mode—that is, after the PreRender event fires.

View State Properties

Table 1 lists all the properties defined in the StateBag class.

Table 1. Properties of the StateBag Class
PropertyDescription
CountGets the number of elements stored in the object.
ItemIndexer property. It gets or sets the value of an item stored in the class.
KeysGets a collection object containing the keys defined in the object.
ValuesGets a collection object containing all the values stored in the object.

Each item in the StateBag class is represented by a StateItem object. An instance of the StateItem object is implicitly created when you set the Item indexer property with a value or when you call the Add method. Items added to the StateBag object are tracked until the view state is serialized prior to the page rendering. Items serialized are those with the IsDirty property set to true.

View State Methods

Table 2 lists all the methods you can call in the StateBag class.

Table 2. Methods of the StateBag Class
MethodDescription
AddAdds a new StateItem object to the collection. If the item already exists, it gets updated.
ClearRemoves all items from the current view state.
GetEnumeratorReturns an object that scrolls over all the elements in the StateBag.
IsItemDirtyIndicates whether the element with the specified key has been modified during the request processing.
RemoveRemoves the specified object from the StateBag object.

The IsItemDirty method represents an indirect way to call into the IsDirty property of the specified StateItem object.

Note

The view state for the page is a cumulative property that results from the contents of the ViewState property of the page plus the view state of all the controls hosted in the page.


2. Common Issues with View State

Architecturally speaking, the importance of the view state cannot be denied, as it is key to setting up the automatic state management feature of ASP.NET. A couple of hot issues are connected to the usage of the view state, however. Most frequently asked questions about the view state are related to security and performance. Can we say that the view state is inherently secure and cannot be tampered with? How will the extra information contained in the view state affect the download time of the page? Let’s find out.

Encrypting and Securing

Many developers are doubtful about using the view state specifically because it is stored in a hidden field and left on the client at the mercy of potential intruders. Although the data is stored in a hashed format, there’s no absolute guarantee that it cannot be tampered with. The first comment I’d like to make in response to this is that the view state as implemented in ASP.NET is inherently more secure than any other hidden fields you might use (and that you were likely using, say, in old classic ASP applications). My second remark is that only data confidentiality is at risk. While this is a problem, it is minor compared to code injection.

Freely accessible in a hidden field named __VIEWSTATE, the view state information is, by default, hashed and Base64 encoded. To decode it on the client, a potential attacker must accomplish a number of steps, but the action is definitely possible. Once decoded, though, the view state reveals only its contents—that is, confidentiality is at risk. However, there’s no way an attacker can modify the view state to post malicious data. A tampered view state, in fact, is normally detected on the server and an exception is thrown.

For performance reasons, the view state is not encrypted. If needed, though, you can turn the option on by acting on the web.config file, as follows:

<machineKey validation="3DES" />

When the validation attribute is set to 3DES, the view-state validation technique uses 3DES encryption and doesn’t hash the contents.

Machine Authentication Check

The @Page directive contains an attribute named EnableViewStateMac, whose only purpose is making the view state a bit more secure by detecting any possible attempt at corrupting the original data. When serialized, and if EnableViewStateMac is set to true, the view state is appended with a validator hash string based on the algorithm and the key defined in the <machineKey> section of the configuration file. The resulting array of bytes, which is the output of the StateBag’s binary serialization plus the hash value, is Base64 encoded. By default, the encryption algorithm to calculate the hash is SHA1, and the encryption and decryption keys are auto-generated and stored in the Web server machine’s Local Security Authority (LSA) subsystem. The LSA is a protected component of Windows NT, Windows 2000, Windows Server 2003, and Windows XP. It provides security services and maintains information about all aspects of local security on a system.

If EnableViewStateMac is true, when the page posts back, the hash value is extracted and used to verify that the returned view state has not been tampered with on the client. If it has been, an exception is thrown. The net effect is that you might be able to read the contents of the view state, but to replace it you need the encryption key, which is in the Web server’s LSA. The MAC in the name of the EnableViewStateMac property stands for Machine Authentication Check, which is enabled by default. If you disable the attribute, an attacker could alter the view-state information on the client and send a modified version to the server and have ASP.NET blissfully use that tampered-with information.

To reinforce the security of the view state, in ASP.NET 1.1 the ViewStateUserKey property has been added to the Page class. The property evaluates to a user-specific string (typically, the session ID) that is known on the server and hard to guess on the client. ASP.NET uses the content of the property as an input argument to the hash algorithm that generates the MAC code.

Size Thresholds and Page Throughput

My personal opinion is that you should be concerned about the view state, but not for the potential security holes it might open in your code—it can let hackers exploit only existing holes. You should be more concerned about the overall performance and responsiveness of the page. Especially for feature-rich pages that use plenty of controls, the view state can reach a considerable size, measured in KB of data. Such an extra burden taxes all requests, in downloads and uploads, and ends up creating serious overhead for the application as a whole.

What would be a reasonable size for an ASP.NET page? And for the view state of a page? Let’s take a look at a sample page that contains a grid control bound to about 100 records (the Customers table in the Northwind database of SQL Server):

<html>
<head runat="server">
    <title>Measure Up Your ViewState</title>
</head>
<script language="javascript">
function ShowViewStateSize()
{
    var buf = document.forms[0]["__VIEWSTATE"].value;
    alert("View state is " + buf.length + " bytes");
}
</script>
<body>
    <form id="form1" runat="server">
        <input type="button" value="Show View State Size"
               onclick="ShowViewStateSize()">
        <asp:SqlDataSource ID="SqlDataSource1" runat="server"
               SelectCommand="SELECT companyname, contactname, contacttitle
                              FROM customers"
               ConnectionString="<%$ ConnectionStrings:LocalNWind %>"
        <asp:DataGrid ID="grid" runat="server"
               DataSourceID="SqlDataSource1" />
    </form>
</body>
</html>


					  

In ASP.NET 2.0 and beyond, the total size of the page is about 20 KB. The view state alone, though, takes up about 11 KB. If you port the same page back to ASP.NET 1.x, results are even worse. The whole page amounts to 28 KB, while the view state alone amounts to a burdensome 19 KB. Two conclusions can be drawn from these numbers:

  • Starting with ASP.NET 2.0, the view-state field appears to be more compact.

  • The view state takes up a large share of the downloaded bytes for the page. You won’t be too far from the truth if you estimate the view-state size to be about 60 percent of the entire page size.

What can you do about this? First, let’s play with some numbers to determine a reasonable goal for view-state size in our applications. You should endeavor to keep a page size around 30 KB, to the extent that is possible of course. For example, the Google home page is less than 4 KB. The home page of http://www.asp.net amounts to about 50 KB. The Google site is not written with ASP.NET, so nothing can be said about the view state. But what about the view-state size of the home of http://www.asp.net? Interestingly enough, that page has only 1 KB of view state. On the other hand, the page http://www.asp.net/ControlGallery/default.aspx?Category=7&tabindex=0 is larger than 130 KB, of which 10 KB is view state. (This page has been redesigned lately; a few months ago, I measured it to be 500 KB in size, with 120 KB of view state!)

The ideal size for a view state is around 7 KB; it is optimal if you can keep it down to 3 KB or so. In any case, the view state, regardless of its absolute size, should never exceed 30 percent of the page size.

Note

Where do these numbers come from? “From my personal experience,” would perhaps be a valid answer, but not necessarily a good and exhaustive one. Let’s put it this way: the smallest you can keep a page is the best size. To me, 30 KB looks like a reasonable compromise, because most things can be stuffed into that size. Clearly, if you have 250 items to display, your page size can grow up to 1 MB or so. In the end, having a smaller or larger view state is a design choice and is mostly application-specific. Within these boundaries, though, a few guidelines can be stated. The most important guideline is not so much that view state should be limited to a few KB, but that it should take a minimal percentage of the overall page size. Which percentage? Being the view-state helper, I’d say no more than 25 percent or 30 percent at the most. But here I’m just throwing out numbers using a bit of common sense. If you can disable the view state altogether, do it. At the very least, you should avoid storing there the avoidable items that don’t change often and are easily cached on the server, such as a long list of countries.

Other  
 
Top 10
Review : Sigma 24mm f/1.4 DG HSM Art
Review : Canon EF11-24mm f/4L USM
Review : Creative Sound Blaster Roar 2
Review : Philips Fidelio M2L
Review : Alienware 17 - Dell's Alienware laptops
Review Smartwatch : Wellograph
Review : Xiaomi Redmi 2
Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
REVIEW
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
VIDEO TUTORIAL
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
Popular Tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8