Wednesday, November 9, 2011

ViewState in ASP.NET


Introduction

Microsoft ASP.NET Web Forms pages are capable of maintaining their own state across multiple client round trips. When a property is set for a control, the ASP.NET saves the property value as part of the control's state. To the application, this makes it appear that the page's lifetime spans multiple client requests. This page-level state is known as the view state of the page. In Web Forms pages, their view state is sent by the server as a hidden variable in a form, as part of every response to the client, and is returned to the server by the client as part of a postback. In this article we will see how View State is implemented in ASP.NET for state management and we will also see how effectively you can use this object in your web form.

Problems with ViewState

Viewstate has lots of advantages and as well as disadvantages, so you need to weigh carefully before making the decision to use it. As I told you early, view state doesnt require any server resources for its operation. It is passed to the client during every postback as an hidden element. Since it is added with every page, it adds few Kbytes to the page. This effects the loading of the page in the client. Other main problem with Viewstate is, since it is passed as plain text to the client. Anybody can tamper this value, because of this you shouldnt store any important data in the viewstate. View state is one of the most important features of ASP.NET, not so much because of its technical relevance, but more because it makes the magic of the Web Forms model possible. However, if used carelessly, view state can easily become a burden. Although ViewState is freely accessible in a hidden field called __VIEWSTATE, the view state information is not clear text. By default, a machine-specific authentication code is calculated on the data and appended to the view state string. The resulting text is then Base64 encoded only, but not encrypted. In order to make the view state more secure, the ASP.NET @Page directive supports an attribute called EnableViewStateMac whose only purpose is detecting any possible attempt at corrupting original data.

Implementation of ViewState

StateBag implements the view state and manages the information that ASP.NET pages and embedded controls persist across successive posts of the same page instance. The class works like a dictionary object and implements the IStateManager interface. The Page and the Control base classes expose the view state through the ViewState property. So you can add or remove items from StateBag as you would with any dictionary object:
                                               ViewState("FontSize") = value

   You should start writing to the view state only after the Init event is fired for a page request. You can read from the view state during any stage of the page lifecycle, but not after the page enters rendering mode—that is, after the PreRender event is fired.
  The contents of the StateBag collection are first serialized to a string, then Base64 encoded, and finally assigned to a hidden field in the page that is served to the client. 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.

Decision on ViewState Usage

As We 've discussed here, the view state represents the state of the page and its controls just before the page is rendered in HTML. When the page posts back, the view state is recovered from the hidden field, deserialized, and used to initialize the server controls in the page and the page itself. However, this is only half the story.
After loading the view state, the page reads client-side information through the Request object and uses those values to override most of the settings for the server controls. In general, the two operations are neatly separated and take place independently. In particular, though, the second operation—reading from Request.Form—in many situations ends up just overriding the settings read out of the view state. In this particular case the view state is only an extra overhead. For example consider the following case, we have one textbox in the page and a link button. If you are typing the some  values in to the textbox and the posting the page using linkbutton. After postback, value in the textbox is retained though you enable or disable the viewstate. In this case you shouldnt enable viewstate for this textbox. Viewstate value is overridden by request.form values, since loadpostdata fires after loadviewstate view event in the Page lifecycle.
But if you consider that readonly property of textbox  is set to False by default. Then in the Page_Load if you are trying to change its readonly property to true based on certain condition. So after setting readonly property in Page_Load and if it is posted back by clicking linkbutton. To retain its readonly property across postback, we need to enable viewstate for this property. Otherwise this property wont be retained across postback.

Viewstate in DataGrid

If you have Set EnableViewState to true for a DataGrid which is having thousands of record. Then you will end up having viewstate size more than 10 KBytes. But if you disable viewstate, you will not be able to fire any events in DataGrid. Postback and acting on postback relies on Viewstate. So if it is readonly datagrid and if you are not going to use paging and sorting provided by datagrid, then you can disable viewstate. But if you want use above mentioned feature of DataGrid, then you can not disable ViewState in DataGrid. So to avoid excessive load on client machine because of viewstate . You can disable viewstate for each item in DataGrid. Disabling can be done in two ways, one way is disabling each itemtemplate columns viewstate to false.
<asp:TemplateColumn headertext="ProductID">
      <ItemTemplate>
            <asp:TextBox id="ProductID" runat="server"  EnableViewState="False" >
            </asp:TextBox>
       </ItemTemplate>
</asp:TemplateColumn>
Other way is by disabling viewstate for each datagrid item in Pre-Render event handler.
Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles
                                                                                                         MyBase.PreRender
              Dim dgi As DataGridItem
              For Each dgi In DataGrid1.Items
                          dgi.EnableViewState = False
               Next
End Sub

Conclusion

The view state is a key element of an ASP.NET page because it is the primary means to persist the state of the Web server controls. Whenever the page posts back, the state is restored, updated using the current form parameters, then used to run the postback event handler. Normally, the view state is a hashed string encoded as Base64 and stored in a hidden field called __VIEWSTATE. In this way, the view state is not cached on the client, but simply transported back and forth with potential issues both for security and performance. Since it is performance overhead, you need to decide properly when and where you should use viewstate in your webform.