Scott on Writing

Musings on technical writing...

Question: I set my page's EnableViewState property False; why is there still a __VIEWSTATE hidden form field?

ANSWER: A while back I wrote an article for MSDN online titled Understanding ASP.NET View State, and blogged about the article in this past entry. I recently noticed a comment in that blog entry from Matthias Cavigelli, asking:

When I disable the ViewState property of the page, I still have the hidden field __VIEWSTATE in the html code. Could you explain why it's still there although it's not enabled?

What Matthias is referring to is the EnableViewState property, which is defined in the System.Web.UI.Control class (which means that all ASP.NET server controls have this property, including the Page class from which all ASP.NET Web pages are derived.) This property defaults to True, which means that, by default, a control should track its view state and save its view state during the SaveViewState stage of the page's lifecycle. By setting EnableViewState to false, a control is saying, "Don't bother recording my view state."

Setting EnableViewState to False on certain state-heavy controls is a good way to trim the size of a page's view state. Of course, you must take care when tweaking this property, since the state-heavy controls typically rely on the view state to maintain their functionality. Here's a good example of when you can set EnableViewState to False: when you have a DataGrid Web control on a page that simply displays data, and where the DataGrid's properties are not programmatically changed on postback. (Note: if this page does have postbacks you'll have to make sure to rebind the database data to your DataGrid on every postback.)

If your page does not perform any postbacks at all, having view state is a big waste. So, you might as well set the Page class's EnableViewState to False, so that no view state is saved for the entire page. Or so you'd think. If you set EnableViewState to False for the page, you'll still get a hidden __VIEWSTATE form field, although it will be pretty small. Why does this hidden form field exist at all?

To answer this question it is important to realize that view state really is paramount to Web Forms, not the Page class. (A Web Form is a server-side <form> tag, which is represented in the .NET Framework via the System.Web.UI.HtmlControls.HtmlForm class.) If a Web Form exists, there typically needs to be a hidden __VIEWSTATE form field. But the Web Form does not know the complete view state of the page. The Page class, for instance, has a ViewState property, into which a page developer can store items into the view state. The Web Form, obviously, is ignorant about this. So there's this chicken-and-egg thing going on here - the Page knows how to completely represent the view state, but it's the Web Form that cares about it, not the Page. The end result is that the Page class is responsible for generating the hidden __VIEWSTATE form field, but it's the Web Form that knows whether or not this is needed.

To overcome this hurdle, the Page class needs some way to know whether or not the __VIEWSTATE form field needs to be emitted or not. To allow for this, the Page class provides a public RegisterViewStateHandler() method; if this method is called during the page lifecycle, a __VIEWSTATE hidden form field will be emitted, even if the Page class's EnableViewState property is set to False.

From a Web Form's perspective, it always needs to save view state. Well, this is the way the Web Form class was programmed by Microsoft. You can see this by examining the HtmlForm class's OnInit() method:

protected override void OnInit(EventArgs e)
{
      base.OnInit(e);
      this.Page.SetForm(this);
      this.Page.RegisterViewStateHandler();
}

Personally, it would seem to make more sense to me to have Page.RegisterViewStateHandler() called only if Page.EnableViewState is true, but there may be a reason behind this that I haven't seen. Anywho, when the Web Form is rendered, it calls an additional two of the Page class's methods:

  1. OnFormRender() - this adds the __VIEWSTATE hidden form field along with any registered hidden form fields or script blocks registered via Page.RegisterClientScriptBlock().
  2. OnFormPostRender() - this adds any script blocks registered via Page.RegisterStartupScript() and any client-side arrays registered via Page.RegisterArrayDeclaration().

You may still be wondering why when the Page's EnableViewState is False that the __VIEWSTATE hidden form field has anything in it. Well, if you take a look at the Page class's SavePageViewState() method, you'll see:

internal void SavePageViewState()
{
      if (!this._needToPersistViewState)
      {
            return;
      }
      Triplet triplet1 = new Triplet();
      int num1 = this.GetTypeHashCode();
      triplet1.First = num1.ToString(NumberFormatInfo.InvariantInfo);
      triplet1.Third = this._registeredControlsThatRequirePostBack;
      ...
      triplet1.Second = base.SaveViewStateRecursive();
      
      this.SavePageStateToPersistenceMedium(triplet1);
}

So what you see her is the following: if _needToPersistViewState is False, then nothing is saved. Well, this flag is set to True when the Web Form calls Page.RegisterViewStateHandler(). So a Triplet is built up, with the first item containing the page's hash, the third item containing an ArrayList of Web controls that require a postback. Now, the second item is where the meat of the view state comes from - this is the sum of the view state of the controls in the page. But if EnableViewState is False for the page, SaveViewStateRecursive() returns null.

So even if you set the Page's EnableViewState to False, you'll still get a __VIEWSTATE hidden form field with the Page's hash and ArrayList of controls that require postback. I still don't see why this is needed, but there is likely a good reason.

In an upcoming article of mine for MSDN online, I talk more about the Page class's methods for registering client-side elements - scripts, arrays, hidden form fields, etc. Keep your eyes peeled on the ASP.NET Dev Center!

posted on Friday, July 23, 2004 2:54 PM

Feedback

# re: Question: I set my page's EnableViewState property False; why is there still a __VIEWSTATE hidden form field? 8/6/2004 3:16 AM Mahalakshmi Natarajan

That was a fine and clear explanation, but still wanting to know why we still get a __VIEWSTATE hidden form field with its details mentioned by you when it is disabled.

# re: Question: I set my page's EnableViewState property False; why is there still a __VIEWSTATE hidden form field? 8/6/2004 8:03 AM Scott Mitchell

Mahalakshmi, I believe your question is answered in this blog post. You get a __VIEWSTATE because the OnFormRender() method is called regardless of whether or not Page.EnableViewState is true or false. This is what emits the __VIEWSTATE hidden form field. The reason this hidden form field contains data, is because a Triplet is created in the Page's SavePageViewState() method, even if Page.EnableViewState is false (although the Second item in the Triplet is not populated).

Hence, you'll get a __VIEWSTATE hidden form field (b/c OnFormRender() is called) with some data in it (because SavePageViewState() still generates the outter Triplet even if Page.EnableViewState is false). This is WHY it happens. Now, if your question is why SHOULD it happen... well, that I am not so sure of. Perhaps an oversight by Microsoft, or perhaps there is a solid reason that is escaping me.

# re: Question: I set my page's EnableViewState property False; why is there still a __VIEWSTATE hidden form field? 10/18/2004 5:02 AM vickram

so going by your explanation. It seems that the statement "if (!this._needToPersistViewState)" in the "internal void SavePageViewState()" method will NEVER return null. right?

# re: Question: I set my page's EnableViewState property False; why is there still a __VIEWSTATE hidden form field? 11/29/2004 5:51 PM Scott Mitchell

To answer your question, vickram, the _needToPersistViewState will be false if there is no Web Form on the page (i.e., if the page does NOT contain <form runat="server">). If the page contains a Web Form, then _needToPersistViewState will be true by the time the Page's SavePageViewState() method runs.

# re: Question: I set my page's EnableViewState property False; why is there still a __VIEWSTATE hidden form field? 2/12/2005 11:07 AM Jeff Ratcliff

Thanks for the informative entry.

I'm learning ASP.NET with the goal of MS Certification. I was experimenting with disabling ViewState and was surprised to see it still appear in the source. Now at least I know it's normal behavior.

I wonder if this curious behavior will continue in ASP.NET 2.0.

# re: Question: I set my page's EnableViewState property False; why is there still a __VIEWSTATE hidden form field? 9/1/2005 5:01 PM Sam

I wonder if you've found any more about the mysterious *third* entry at page level. Is this a list of IDs for *every* control that can receive a postback event or does a control have to do something special to be included? Seems like the former.

Anyway, it is really blowing up my viewstate with a datagrid since the datagrid contains many postback links. Turning page level viewstate off doesn't help much for the reasons you gave. Could this be some ASP.NET security check to make sure a user doesn't spoof the __doPostBack control ID and cause unforseen effects?

# re: Question: I set my page's EnableViewState property False; why is there still a __VIEWSTATE hidden form field? 9/2/2005 10:10 AM Sam

Hi Scott,

It seems that every control that is called with Page.RegisterRequiresPostBack(control) is put into this third triplet. The documentation says that it "Registers a control as one that requires post-back handling" so probably no Page level events will be fired for the control unless it is in the third triplet if you call this method. However, you do not *have* to call this method and the control still works fine, at least in my limited testing.

My DataGrid contains a lot of ImageButtons and CheckBoxes so the only way I can make Viewstate smalller is to implement these myself from BaseServerControl.

Kudos to Microsoft for the great documentation!

# re: Question: I set my page's EnableViewState property False; why is there still a __VIEWSTATE hidden form field? 9/2/2005 10:49 AM Sam

I take it back. You *do* have to implement this method if you want form data to be repopulated. However, my particular version of ImageButton uses the doPostBack() and not the form data, so I can save ViewState there by not calling RegisterRequiresPostBack(). I am out of luck for my checkbox columns, since they inherently require form data to be posted and hence RegisterRequiresPostBack() to be called on them.

# re: Question: I set my page's EnableViewState property False; why is there still a __VIEWSTATE hidden form field? 10/3/2005 9:39 AM Peter Droppa

To Sam: I had the same problem - long DataList with ImageButtons that were blowing up the ViewState. However I found out that LinkButton doesn't occur in that *third* list. So I have exchanged <asp:ImageButton ...></asp:ImageButton> with <asp:LinkButton ...><img src="..." ...></asp:LinkButton>. Seems to work well this way, saving ViewState's space.

# re: Question: I set my page's EnableViewState property False; why is there still a __VIEWSTATE hidden form field? 12/5/2005 2:27 PM Pete A

I am a contractor web developer here in CA working at a company where the production environment comprises two web sites located on two separate networks (the first owned by the company, and the second is hosted by a second-party company). The two web sites
have the same domain name but different IP addresses on the DNS on the internet, and there is no load balancing mechanism in place,
so a request could go to either IP address.
Anyway, to make the web application work, I have to disable session state and view state so that it does not matter to which website
each request goes.

My question is: with the viewstate disabled both at the page level and web control level, the hidden field still appears on the page. Does the field _ViewState still go through a validation process on the server even if
viewstate is disabled?

I am getting an error message "unable to validate data" and "Authentication of ViewState failed" every time the request goes from one web server to the second server.



# re: Question: I set my page's EnableViewState property False; why is there still a __VIEWSTATE hidden form field? 1/31/2006 7:50 AM Ricardo Sánchez

To Pete A: Simply disable the viewstatemac property at the page level.

# __VIEWSTATE | keyongtech 1/21/2009 10:29 PM Pingback/TrackBack

__VIEWSTATE | keyongtech

Title:  
Name:  
Url:
Protected by Clearscreen.SharpHIPEnter the code you see:
Comments   

My Links

Ads Via DevMavens

Archives

Post Categories

 

I am a Microsoft MVP for ASP.NET.
I am an ASPInsider.
<July 2009>
SMTWTFS
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

Comment Stats

DayTotal% of Total
Sunday 2046.9%
Monday 42314.3%
Tuesday 50116.9%
Wednesday 54518.4%
Thursday 57219.3%
Friday 53618.1%
Saturday 1856.2%
Total 2966100.0%

Hour1Total% of Total
12:00 AM 752.5%
1:00 AM 802.7%
2:00 AM 672.3%
3:00 AM 812.7%
4:00 AM 642.2%
5:00 AM 1234.1%
6:00 AM 1153.9%
7:00 AM 1755.9%
8:00 AM 1876.3%
9:00 AM 1565.3%
10:00 AM 1866.3%
11:00 AM 1926.5%
12:00 PM 1996.7%
1:00 PM 1846.2%
2:00 PM 1675.6%
3:00 PM 1344.5%
4:00 PM 1153.9%
5:00 PM 1063.6%
6:00 PM 993.3%
7:00 PM 1063.6%
8:00 PM 903.0%
9:00 PM 842.8%
10:00 PM 893.0%
11:00 PM 923.1%
Total 2966100.0%

Comments by Blog Entry Date/Time

Day Entry MadeAvg.Total
Sunday 4.91157
Monday 4.92379
Tuesday 4.21471
Wednesday 7.42668
Thursday 6.53666
Friday 5.17450
Saturday 4.73175
Total 5.522966

Hour1 Entry MadeAvg.Total
12:00 AM 5.2937
1:00 AM 1.002
5:00 AM 0.000
7:00 AM 4.0048
8:00 AM 4.29133
9:00 AM 6.04290
10:00 AM 5.83274
11:00 AM 4.36192
12:00 PM 6.44348
1:00 PM 3.14132
2:00 PM 5.04227
3:00 PM 7.97303
4:00 PM 3.8199
5:00 PM 6.00168
6:00 PM 4.56114
7:00 PM 8.95188
8:00 PM 8.58163
9:00 PM 5.00115
10:00 PM 6.31101
11:00 PM 4.5732
Total 5.522966

Learn More About Comment Stats
1 - All times GMT -8...


Blog Stats

Favorite Web Sites

My Books

My MSDN Articles