Using client-based state management techniques involves storing information between calls to the server in the final HTML page, in an HTTP request, or on the disk cache of the client computer. The server itself stores no information between round-trips and uses the client information passed to it on each call to rebuild the state of the prior page invocation. The client uses ViewState, hidden fields, cookies, or query strings to store and forward state between server calls. Let’s look at the details of these state management mechanisms and discuss a few benefits and drawbacks of each.
ViewState: The default behavior
By default, an ASP.NET page uses ViewState on the page to preserve page and control property values between round-trips. When each page is processed, the ASP. NET engine hashes the current state of the page and each control on the page into a string and passes the string to the client browser in a hidden field. When the client posts the page back to the server, ASP.NET parses the hidden field during page initialization and restores the page and control values back to their prior state.
Developers can also save their own values in ViewState and they will automatically be restored. For example, if you want to store a value called BackColor between round-trips, you can create the variable in ViewState and set its value like this:
ViewState(“BackColor”) = “Blue”
Using ViewState has several key advantages. Since its use is automatic, it requires no configuration to implement. By default, all page and control states are maintained automatically. ViewState is also very secure because the values are hashed, compressed, and encoded automatically, where a standard hidden field is in clear text. But ViewState is not a panacea. Since ASP.NET stores the ViewState in the page, a page with several controls or controls with a large number of values (i.e., a data grid with a few hundred rows) can make both loading and posting a page dramatically slower. In general, you will want to turn ViewState off for controls that contain a large amount of read-only data.
Hidden form fields: The old standard
Developers may also choose to store page-specific information in a hidden field on a page to maintain the state of the page. When the browser submits the page to the server, the server page can retrieve the content of the hidden field from the HTTP form collection along with the values of other controls. Many ASP implementations use hidden fields as a way to maintain client state, and you may choose to continue using this approach when migrating existing applications from ASP to ASP.NET.
Hidden fields are simple to implement and are supported by all browsers and client devices. But there are significant disadvantages to using hidden fields. Users can see the value of a hidden field by simply viewing the page source. Moreover, although you can store simple name-value pairs in a hidden field, you have to create your own storage and parsing mechanism for saving multiple values within a hidden field. For example, you might implement string delimiters and a string parsing mechanism to store multiple values in a single field. As with ViewState, large values in hidden fields will cause the page to slow down when displaying and posting back the page.
For storing a small number of frequently changed values, cookies are an ideal client-side state mechanism. Cookies are text files on the client’s file system managed by the browser. It’s a local caching mechanism that allows the server to send page-specific information in addition to the standard page output. When creating a cookie, the server can define them to be temporary with given expiration times and dates, or persistent. When the user posts back to a page, the browser returns the cookie information to the server, allowing developers to access the cookie information when processing the page.
Like other client-side mechanisms, cookies require no server resources and their values are accessible to the server after a post. They are a simple, lightweight structure and allow text-based storage of key-value pairs. One key advantage of cookies is that they’re the only client-side state mechanism that can survive between page calls and also between invocations of the application itself. This allows the developer to store application configuration or application usage history information that can be used any time someone accesses the application from the same browser on the same machine.
But the usefulness of cookies as a state management mechanism is diminished by the inability to store more than 4,096 bytes per cookie. Although some newer browsers and devices allow 8,192 bytes, developers who want to maintain backward compatibility will need to limit their cookie size to 4,096 bytes.
For situations where you want to pass a limited amount of information between pages, a query string may be an ideal choice. The query string consists of information passed between pages by appending name-value pairs to a URL. For example, you may have one page that allows a user to select a customer to view and then pass the selected CustomerID to another page for processing by appending CustomerID=1234 to the URL.
Query strings are lightweight state mechanisms passed in the HTTP request that target a specific URL. Further, all browsers and client devices, even the simplest devices like WAP phones, support query strings. However, because the information passed in the query string is visible to the user by simply looking at the URL, it may pose a security risk for all but the most trivial implementations. And since most browsers limit the length of a URL to 255 characters, the amount of information that you can pass using a query string is severely limited.
In fact, the most common use of the query string is to pass a hashed session value between page invocations, allowing developers to use server-side state without storing the session value in a cookie or depending on standard ASP.NET session state mechanisms. I’ll look at these and other server-side session state issues in my next column.