As I said before, the web server doesn't care about user information or condition. If you were creating a form that would post back to itself, it would be your job as a designer to maintain the information a user entered into the form across posts; otherwise, the information the user inserted would be lost when the page was delivered back. The following is a simple example of this in traditional ASP.
<%@LANGUAGE="VBSCRIPT"%> <%dim vFirstName,vLastName,vPhone,vEmail vFirstName = "" vLastName = "" vPhone = "" vEmail = "" if Request.Form("submit") <> "" then vFirstName = Request.Form("firstname") vLastName = Request.Form("lastname") vPhone = Request.Form("phone") vEmail = Request.Form("email") end if %> <html> <head> <title>Traditional ASP - Page State</title> </head> <body> <form name="form1" method="post" action=""> <input type="text" name="firstname" value="<%=vFirstName%>"> First Name<br> <input type="text" name="lastname" value="<%=vLastName%>"> Last Name<br> <input type="text" name="phone" value="<%=vPhone%>"> Phone Number<br> <input type="text" name="email" value="<%=vEmail%>"> Email Address<br> <input type="submit" name="Submit" value="Submit"> </form> </body> </html>
Yes, I know there are shorter ways to do this, but I really wanted to demonstrate what is necessary to repopulate form text boxes.
Now let's take a look at a similar page in ASP.NET, and observe what you have to do to maintain the state of the TextBox server controls.
<html> <head> <title>Traditional ASP - Page State</title> </head> <body> <form runat="server"> <asp:TextBox runat="server" /> First Name<br> <asp:TextBox runat="server" /> Last Name<br> <asp:TextBox runat="server" /> Phone Number<br> <asp:TextBox runat="server" /> Email Address<br> <asp:Button text="Submit" runat="server" /> </form> </body> </html>
Do you see how it's done? Look really hard! Still don't see it? No matter how hard you look, you ain't gonna see it because there's nothing there. ASP.NET handles page-level state for you without you lifting a finger. Actually, the only time you need to write any code with reference to maintaining page state in an ASP.NET web form is if you DON'T WANT IT!! That is correct. If you don't want to maintain state, you have to explicitly say so.
For you to see the magic you would have to look at the delivered page's source code. The preceding page's rendered source code looks like this:
<html> <head> <title>Traditional ASP - Page State</title> </head> <body> <form name="_ctl0" method="post" action="dotnet_page_state.aspx" > <input type="hidden" name="__VIEWSTATE" value= "dDwtMTE4NzE2NjU2MDs7PkesEtdwWxQyics7BpduSPBkw6L/" /> <input name="FirstName" type="text" /> First Name<br> <input name="LastName" type="text" /> Last Name<br> <input name="Phone" type="text" /> Phone Number<br> <input name="Email" type="text" /> Email Address<br> <input type="submit" name="Submit" value="Submit" /> </form> </body> </html>
The secret lies in the hidden input field called __VIEWSTATE, which is at the core of ASP.NET's capability to maintain the state of an ASP.NET page. Data about the condition and information on a web form is stored in this <input type="hidden"> tag named __VIEWSTATE.
ViewState isn't necessary at all times, and at times it can be pretty costly because it can become quite bloated with conditions and information for a page with many controls or large DataGrids on it. For instance, if you look at Figure 11.1, you will see a DataGrid from an example in Chapter 9. In the original example I didn't have a <form runat="server"> tag on the page, so no ViewState was created, but for demonstration I took that simple DataGrid with the Top 10 products in the Northwind database and wrapped it in a <form runat="server"> tag so a __ViewState would be created. Here is the generated ViewState:
<input type="hidden" name="__VIEWSTATE" value="dDwtNTcyNzE4MDk2O3Q8O2w8aTwxPjs+O2w8dDw7bDxpPDE+Oz47bDx0PEAwPHA8cDxsPFBhZ2V Db3VudDtfIUl0ZW1Db3VudDtfIURhdGFTb3VyY2VJdGVtQ291bnQ7RGF0YUtleXM7PjtsPGk8MT47aTwxM D47aTwxMD47bDw+Oz4+Oz47Ozs7Ozs7OztAMDxAMDxwPGw8SGVhZGVyVGV4dDtEYXRhRmllbGQ7U29ydEV 4cHJlc3Npb247UmVhZE9ubHk7PjtsPFByb2R1Y3ROYW1lO1Byb2R1Y3ROYW1lO1Byb2R1Y3ROYW1lO288Z j47Pj47Ozs7PjtAMDxwPGw8SGVhZGVyVGV4dDtEYXRhRmllbGQ7U29ydEV4cHJlc3Npb247UmVhZE9ubHk 7PjtsPFF1YW50aXR5UGVyVW5pdDtRdWFudGl0eVBlclVuaXQ7UXVhbnRpdHlQZXJVbml0O288Zj47Pj47O zs7PjtAMDxwPGw8SGVhZGVyVGV4dDtEYXRhRmllbGQ7U29ydEV4cHJlc3Npb247UmVhZE9ubHk7PjtsPFV uaXRQcmljZTtVbml0UHJpY2U7VW5pdFByaWNlO288Zj47Pj47Ozs7PjtAMDxwPGw8SGVhZGVyVGV4dDtEY XRhRmllbGQ7U29ydEV4cHJlc3Npb247UmVhZE9ubHk7PjtsPFVuaXRzSW5TdG9jaztVbml0c0luU3RvY2s 7VW5pdHNJblN0b2NrO288Zj47Pj47Ozs7Pjs+Oz47bDxpPDA+Oz47bDx0PDtsPGk8MT47aTwyPjtpPDM+O 2k8ND47aTw1PjtpPDY+O2k8Nz47aTw4PjtpPDk+O2k8MTA+Oz47bDx0PDtsPGk8MD47aTwxPjtpPDI+O2k 8Mz47PjtsPHQ8cDxwPGw8VGV4dDs+O2w8Q2hhaTs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8MTAgYm94Z XMgeCAyMCBiYWdzOz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDwxOC4yMzs+Pjs+Ozs+O3Q8cDxwPGw8VGV 4dDs+O2w8Mzk7Pj47Pjs7Pjs+Pjt0PDtsPGk8MD47aTwxPjtpPDI+O2k8Mz47PjtsPHQ8cDxwPGw8VGV4d Ds+O2w8Q2hhbmc7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPDI0IC0gMTIgb3ogYm90dGxlczs+Pjs+Ozs +O3Q8cDxwPGw8VGV4dDs+O2w8MTkuMDI7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPDE3Oz4+Oz47Oz47P j47dDw7bDxpPDA+O2k8MT47aTwyPjtpPDM+Oz47bDx0PHA8cDxsPFRleHQ7PjtsPEFuaXNlZWQgU3lydXA 7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPDEyIC0gNTUwIG1sIGJvdHRsZXM7Pj47Pjs7Pjt0PHA8cDxsP FRleHQ7PjtsPDEwLjE1Oz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDwxMzs+Pjs+Ozs+Oz4+O3Q8O2w8aTw wPjtpPDE+O2k8Mj47aTwzPjs+O2w8dDxwPHA8bDxUZXh0Oz47bDxDaGVmIEFudG9uJ3MgQ2FqdW4gU2Vhc 29uaW5nOz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDw0OCAtIDYgb3ogamFyczs+Pjs+Ozs+O3Q8cDxwPGw 8VGV4dDs+O2w8MjIuOTs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8NTM7Pj47Pjs7Pjs+Pjt0PDtsPGk8M D47aTwxPjtpPDI+O2k8Mz47PjtsPHQ8cDxwPGw8VGV4dDs+O2w8Q2hlZiBBbnRvbidzIEd1bWJvIE1peDs +Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8MzYgYm94ZXM7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPDIxL jM1Oz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDwwOz4+Oz47Oz47Pj47dDw7bDxpPDA+O2k8MT47aTwyPjt pPDM+Oz47bDx0PHA8cDxsPFRleHQ7PjtsPEdyYW5kbWEncyBCb3lzZW5iZXJyeSBTcHJlYWQ7Pj47Pjs7P jt0PHA8cDxsPFRleHQ7PjtsPDEyIC0gOCBveiBqYXJzOz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDwyNTs +Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8MTIwOz4+Oz47Oz47Pj47dDw7bDxpPDA+O2k8MT47aTwyPjtpP DM+Oz47bDx0PHA8cDxsPFRleHQ7PjtsPFVuY2xlIEJvYidzIE9yZ2FuaWMgRHJpZWQgUGVhcnM7Pj47Pjs 7Pjt0PHA8cDxsPFRleHQ7PjtsPDEyIC0gMSBsYiBwa2dzLjs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8M zA7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPDE1Oz4+Oz47Oz47Pj47dDw7bDxpPDA+O2k8MT47aTwyPjt pPDM+Oz47bDx0PHA8cDxsPFRleHQ7PjtsPE5vcnRod29vZHMgQ3JhbmJlcnJ5IFNhdWNlOz4+Oz47Oz47d DxwPHA8bDxUZXh0Oz47bDwxMiAtIDEyIG96IGphcnM7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPDQwOz4 +Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDw2Oz4+Oz47Oz47Pj47dDw7bDxpPDA+O2k8MT47aTwyPjtpPDM+O z47bDx0PHA8cDxsPFRleHQ7PjtsPE1pc2hpIEtvYmUgTmlrdTs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w 8MTggLSA1MDAgZyBwa2dzLjs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8OTc7Pj47Pjs7Pjt0PHA8cDxsP FRleHQ7PjtsPDI5Oz4+Oz47Oz47Pj47dDw7bDxpPDA+O2k8MT47aTwyPjtpPDM+Oz47bDx0PHA8cDxsPFR leHQ7PjtsPElrdXJhOz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDwxMiAtIDIwMCBtbCBqYXJzOz4+Oz47O z47dDxwPHA8bDxUZXh0Oz47bDwzMTs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8MzE7Pj47Pjs7Pjs+Pjs +Pjs+Pjs+Pjs+Pjs+iUF+nF87Ysehxpz4JqGSmZvddnU=" />
Hearty, huh? That's a touch over 3Kb for maintaining state on that DataGrid. Although this looks large (and it is) there may be times when this is the better route to take with regard to the performance of your application. You will need to weigh the requirements of your application to determine how and when to use ViewState. Just for reference, this 3Kb of data will take less than 1 second to download over a 56Kbps modem.
Note |
__VIEWSTATE is generated only when a page has a <form runat="server"> tag. You can have DataGrids on pages without this tag and no __VIEWSTATE will be generated. |
You will generally find ViewState very useful on forms where you want to maintain the condition of the user interface across postbacks.
As I said, you don't need to use ViewState. ASP.NET enables you to control whether an ASP.NET web form handles ViewState, or you can set it on a server control level also. The property of the Page and server controls that controls whether that object's state information will be maintained in ViewState is called EnableViewState.
To set a page's ViewState, you set this property in the @Page directive at the top of the page.
<%@ page language="vb" EnableViewState="False" runat="server"%> <%@ page language="c#" EnableViewState="False" runat="server"%>
This property of the page is true by default, so if you want ViewState enabled on a page, you can either explicitly set it to true or not include the property declaration.
Setting the ViewState of a server control is no different, really, than setting any other property of a control. The following is a block of code from a code example in Chapter 10 where a DropDownList server control was used to filter a DataTable that populates a DataGrid. Because the DataGrid will be filtered and repopulated on each PostBack, its EnableViewState property can be set to false. The DropDownList is a different story. Here it's important to maintain the data and which value was selected across posts. ViewState repopulates the DropDownList and sets it to the value selected before the post.
<html> <head> <title>ADO Store Procedure - Select</title> </head> <body bgcolor="#FFFFFF" text="#000000"> <form runat="server"> <asp:DropDownList runat="server" /> <asp:Button Text="Get Products" runat="server" /><br><br> <ASP:DataGrid EnableViewState="False" BorderWidth="1" BorderColor="#000000" CellPadding="3" CellSpacing="0" Font-Name="Verdana" HeaderStyle-BackColor="#AAAAAA" ItemStyle-BackColor="#EEEEEE" AutoGenerateColumns="False" runat="server"> <Columns> <asp:BoundColumn HeaderText="Product Name" DataField="ProductName" /> <asp:BoundColumn HeaderText="Unit Price" DataField="UnitPrice" DataFormatString="{0:c}"/> </Columns> </asp:DataGrid><br> <asp:Label Font-Name="Verdana" runat="server" /> </form> </body> </html>
This code example causes the DropDownList's state to be maintained, but the DataGrid's state is not maintained in the ViewState.
In the past, when you needed to pass a value back to the server that you didn't want the user to see in the browser window, you would use an <input type="hidden"> tag. ASP.NET provides a object called the StateBag (of which ViewState is really just an instance) for you to pass data back to the server while it's hidden from the user's view.
The StateBag serves this purpose and is treated no differently than any other collection, such as the Request collection or Application collection. You can get and set values of StateBag contents. The following example looks briefly at this.
ViewState("FirstName") = "Peter" ViewState("Publisher") = "New Riders" vFirstName = ViewState("FirstName") vPublisher = ViewState("Publisher")
ViewState["FirstName"] = "Peter" ViewState["Publisher"] = "New Riders" vFirstName = ViewState["FirstName"] vPublisher = ViewState["Publisher"]
As you can see, it's not really that big a deal. You use the word ViewState to address the StateBag collection and place the name of the item you want to set or get in the StateBag you want.
Page state management is a big part of building ASP.NET applications, but you don't usually build one-page applications. Applications can span across many pages, and you need to be able to identify a user from one page to the next. This is where User State and Session State come into play.
Top |