Tuesday, July 31, 2007

ViewState transition

View state is page scoped and is valid for that page only. View state should not be transferred across pages.

The Viewstate structure
The Viewstate field is not crypted. But it has a 2 level coding:

* first all HTML punctuations, like "<", "+", "=" are encoded using a %nn notation. For instance, "+" is coded as "%2B" (where $2B is the Hex value of the ASCII code of ".")
* then the text is "base 64" encoded: to fit all 256 possible byte value in 7 bits, there is a transcoding from 8 to 7 bits.

The resulting decoded string follows a "compact xml" structure, where the elements are all between "<" and ">" and the elements of the tags are triples, pairs, lists arrays and indexes.

The IEBNF (Indented Extended BNF) grammar of this coding is


viewstate= element .
element = triple | pair | list | index .
triple= 't<' element ';' element ';' element '>' .
pair= 'p<' element ';' element '>' .
list= 'l<' { element ';' } .
index= 'i<' value '>' .
value= ANY_BUT ( ';' | '>' ) .

Refernces article


What happens if i do pass it on?

Similar to "ViewState" there are other option to save temporary data like "Cache", "AppDomain"


each one has its own use.
ViewState - Is good for page level data storage, where amount of data is small.
Cache - Is good for large amount of data
AppDomain - Is good for across client commuication.like sharing a specific details across all active clients.



From Another Article

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.

No comments: