分享
 
 
 

ViewState: All You Wanted to Know

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

ViewState: All You Wanted to KnowPaul Wilson

www.WilsonDotNet.com

www.ASPAlliance.com/PaulWilson

Previous Article Page Events and PostBack Next Article

What ViewState is NotFirst, lets consider what ViewState is NOT, since there are several common misconceptions. ViewState does not help restore posted values to form controls, although this is said at times. The easiest way to see this is to disable a controls ViewState and watch its value be restored. This is done automatically for us by matching the posted form variable name with the control, although this only works for controls that are created by the time the Load event is completed. So while ASP.NET does automate the restoring of form values, this is not part of ViewState.

ViewState also does not auto-recreate any controls that were dynamically created in the code. This is actually something that many of us have discovered the hard way, since it doesnt work. Any controls that you dynamically create in your code must therefore be recreated in the code. This can be a little difficult at times to work around, especially for controls created in events, but it is doable if you keep track of whats been previously done and recreate it on each Load. ViewState can, however, be used to track this information, but we must manually code for it.

Finally, ViewState is not intended for user or session data, nor for transferring across pages. ViewState is only designed for state data related to the current page and its various controls. It does not get sent to a new page in any case, not through links, redirects, or server transfers. There may be things that you want to access on multiple pages, due to redirects or transfers, but the solutions involve using either cookies, session, or the request context, not ViewState. We will also see that ViewState is neither secure, nor always the best use of server resources.

So What is ViewStateViewState is used to track and restore the state values of controls that would otherwise be lost, either because those values do not post with the form or because they are not in the page html. This means that a control totally defined in your page html, with no changes made in the code, will have no ViewState at all, as is often the case when using drag-n-drop with static content. Instead, ViewState only holds the values of properties that are dynamically changed somehow, usually in code, data-binding, or user interactions, so that they can be restored on each request.

So, ViewState holds properties you change in code, any data that you bind to a control in code, and any changes that occur as a result of user interactions that were triggered with a PostBack. An example of a user interaction is a user selecting a date or moving a month in the calendar, which triggers a PostBack that changes properties of the calendar to match the users request. The new date selected or month being viewed must be persisted in the calendars ViewState since these are properties that will need to be restored but which will not be posted next time.

ViewState also provides a StateBag, which is a special collection or dictionary, for each page that you can use to store any object or value, associated with a key, to retain across PostBacks. This is useful for your own custom items that are relevant to only that specific page instance, since these values will automatically post with that page, but not transfer to any other pages. One very good use of custom ViewState is to keep track of any dynamically created controls, which you can then manually recreate on each post based on your tracking data in ViewState.

And What is the FormatViewState is by default serialized and passed across page PostBacks as a hidden form field, __VIEWSTATE, that is Base64 encoded so that it is not easily readable, but not encrypted. ViewState is by default tamper-proof, however, since a hash is applied based on machine key, although this is disabled by setting the enableViewStateMac property to false (see Listing 1). ViewState can be optionally encrypted, by setting up machineKey validation (see Listing 2), but this must be done at the machine level and it uses more resources so its not recommended.

ViewState is saved before rendering in the Page.SavePageStateToPersistenceMedium method and it is restored on PostBacks in the Page.LoadPageStateFromPersistenceMedium method. Both of these methods can be easily overridden to save ViewState to Session (see Listing 3), which is useful for low-bandwidth cases, like Mobile devices which use Session by default. Storing the ViewState in other data stores, like a database or even advanced Session modes, requires serialization and deserialization using the special LosFormatter class (see Listing 4).

Finally, lets take a look at the internal format of the ViewState object for completeness sake. Each controls ViewState is stored in a Triplet (System.Web.UI.Triplet) with the First object being a Pair (System.Web.UI.Pair), or Array or Pairs, of ArrayLists of related name-values. The Second object of the Triplet is an ArrayList of that controls child indices in control tree, and the Third object is an ArrayList of the similar associated Triplets of those child controls. Its all rather hard to describe, so look at the example and try it for yourself (see Listings 5/6).

Listing 1: ViewState Machine Hash Disabled

machine.config or web.config: <pages enableViewStateMac='false' />

page level directive: <%@Page enableViewStateMac='false' %>

page level script code: Page.EnableViewStateMac = false;

Listing 2: ViewState Encryption is Enabled

machine.config: <machineKey validation='3DES' validationKey='*' />

where the validationKey must be the same across a web-farm setup

also requires the enableViewStateMac property setting to be true

Listing 3: ViewState Saved in Session State

protected override object LoadPageStateFromPersistenceMedium() {

return Session["ViewState"];

}

protected override void SavePageStateToPersistenceMedium(object viewState) {

Session["ViewState"] = viewState;

// Bug requires Hidden Form Field __VIEWSTATE

RegisterHiddenField("__VIEWSTATE", "");

}

Listing 4: ViewState Saved in Custom Store

protected override object LoadPageStateFromPersistenceMedium() {

LosFormatter format = new LosFormatter();

return format.Deserialize(YourDataStore["ViewState"]);

}

protected override void SavePageStateToPersistenceMedium(object viewState) {

LosFormatter format = new LosFormatter();

StringWriter writer = new StringWriter();

format.Serialize(writer, viewState);

YourDataStore["ViewState"] = writer.ToString();

}

Listing 5: ViewState Decode/Parse Example

Encoded ViewState:

dDwxMjM0NTY3ODkwO3Q8cDxsPHBycEE7cHJwQjtwcnBDOz47bDx2YWxBO3ZhbEI7dmFsQzs+PjtsPGk8

MD47aTwyPjtpPDM+O2k8NT47PjtsPHQ8cDxsPHBycEE7cHJwQjs+O2w8dmFsQTt2YWxCOz4+Ozs+O3Q8

cDxsPHBycEE7cHJwQjs+O2w8dmFsQTt2YWxCOz4+Ozs+O3Q8cDxsPHBycEE7cHJwQjs+O2w8dmFsQTt2

YWxCOz4+Ozs+O3Q8cDxsPHBycEE7cHJwQjs+O2w8dmFsQTt2YWxCOz4+Ozs+Oz4+Oz4=

Decoded ViewState:

t<1234567890;t<p<l<prpA;prpB;prpC;>;l<valA;valB;valC;>>;

l<i<0>;i<2>;i<3>;i<5>;>;l<

t<p<l<prpA;prpB;>;l<valA;valB;>>;;>;

t<p<l<prpA;prpB;>;l<valA;valB;>>;;>;

t<p<l<prpA;prpB;>;l<valA;valB;>>;;>;

t<p<l<prpA;prpB;>;l<valA;valB;>>;;>;>>;>

Parsed ViewState:

t<1234567890; Page-Level Triplet is Special Case

t<p<l<prpA;prpB;prpC;>; Triplet-First:Pair-First:ArrayList

l<valA;valB;valC;> Pair-Second:ArrayList

>;

l<i<0>; Triplet-Second:ArrayList:Indices

i<2>; of the

i<3>; Children

i<5>; Controls

>;

l<t<p<l<prpA;prpB;>; Triplet-Third:ArrayList:Triplets

l<valA;valB;> of the

>; Children

; Controls

>;

t<p<l<prpA;prpB;>; Each Sub-Triplet follows same Pattern

l<valA;valB;>

>;

; More Levels Possible if sub-Children

>;

t<p<l<prpA;prpB;>; Each Sub-Triplet follows same Pattern

l<valA;valB;>

>;

; More Levels Possible if sub-Children

>;

t<p<l<prpA;prpB;>; Each Sub-Triplet follows same Pattern

l<valA;valB;>

>;

; More Levels Possible if sub-Children

>;

>

>; Closing of Special Page-Level Triplet

>

Listing 6: ViewState Decode/Parse Code

protected override void SavePageStateToPersistenceMedium(object viewState) {

// Call Base Method to Not Change Normal Process

base.SavePageStateToPersistenceMedium(viewState);

// Retrieve ViewState and Write Out to Page

LosFormatter format = new LosFormatter();

StringWriter writer = new StringWriter();

format.Serialize(writer, viewState);

string vsRaw = writer.ToString();

Response.Write("ViewState Raw: " + Server.HtmlEncode(vsRaw));

// Decode ViewState and Write Out to Page

byte[] buffer = Convert.FromBase64String(vsRaw);

string vsText = Encoding.ASCII.GetString(buffer);

Response.Write("ViewState Text: " + Server.HtmlEncode(vsText));

// Parse ViewState -- Turn On Page Tracing

ParseViewState(viewState, 0);

}

private void ParseViewState(object vs, int level) {

if (vs == null) {

Trace.Warn(level.ToString(), Spaces(level) + "null");

}

else if (vs.GetType() == typeof(System.Web.UI.Triplet)) {

Trace.Warn(level.ToString(), Spaces(level) + "Triplet");

ParseViewState((Triplet) vs, level);

}

else if (vs.GetType() == typeof(System.Web.UI.Pair)) {

Trace.Warn(level.ToString(), Spaces(level) + "Pair");

ParseViewState((Pair) vs, level);

}

else if (vs.GetType() == typeof(System.Collections.ArrayList)) {

Trace.Warn(level.ToString(), Spaces(level) + "ArrayList");

ParseViewState((IEnumerable) vs, level);

}

else if (vs.GetType().IsArray) {

Trace.Warn(level.ToString(), Spaces(level) + "Array");

ParseViewState((IEnumerable) vs, level);

}

else if (vs.GetType() == typeof(System.String)) {

Trace.Warn(level.ToString(), Spaces(level) + "'" + vs.ToString() + "'");

}

else if (vs.GetType().IsPrimitive) {

Trace.Warn(level.ToString(), Spaces(level) + vs.ToString());

}

else {

Trace.Warn(level.ToString(), Spaces(level) + vs.GetType().ToString());

}

}

private void ParseViewState(Triplet vs, int level) {

ParseViewState(vs.First, level + 1);

ParseViewState(vs.Second, level + 1);

ParseViewState(vs.Third, level + 1);

}

private void ParseViewState(Pair vs, int level) {

ParseViewState(vs.First, level + 1);

ParseViewState(vs.Second, level + 1);

}

private void ParseViewState(IEnumerable vs, int level) {

foreach (object item in vs) {

ParseViewState(item, level + 1);

}

}

private string Spaces(int count) {

string spaces = "";

for (int index = 0; index < count; index++) {

spaces += " ";

}

return spaces;

}

Author BioPaul Wilson is a software architect in Atlanta, currently with a medical device company. He specializes in Microsoft technologies, including .NET, C#, ASP, SQL, COM+, and VB. His WilsonWebForm Control allows Multiple Forms and Non-PostBack Forms in ASP.NET. He is a Microsoft MVP in ASP.NET and is also recognized as an ASPFriend's ASPAce/ASPElite. He is a moderator on Microsoft's ASP.NET Forums, as well as one of the top posters. He is certified in .NET (MCAD), as well as also holding the MCSD, MCDBA, and MCSE. Please visit his website, www.WilsonDotNet.com, or email him at Paul@WilsonDotNet.com.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有