返回首页

摘要
在以下几行,生病显示了如何创建一个非常简单的浏览器,显示在控件的视图状态存储的内容。它不只是一棵树,所有的__VIEWSTATE字段中存储的ViewState数据,但所有的数据存储在ViewState中,并在每个控件的视图状态保存数据的控制清单。因此,这将显示ASP.NET如何安排数据就保存在ViewState的控件,这些控件中的每一个保留的数据。问题
介绍了在ASP.NET回发机制的一部分,微软创建的ViewState的方法来减少回发页面创建时间。背后ViweState的想法很简单:而首次创建的页面,一些控制数据从数据源(如数据库)中提取。当用户开始从客户端的服务器事件,所有的页面控件重建过程中传入的服务器端的事件。为了防止访问数据源控件的数据,这是不使用HTML形式发送,它可以被序列化到一个隐藏的文本字段(__VIEWSTATE),发送到客户端的HTML表单的一部分。当一个服务器端事件是必需的,隐藏的__VIEWSTATE领域拥有控制序列化的数据发送到服务器。 ASP.NET可以使用的__VIEWSTATE字段保存的数据访问数据存储得到控制数据,而不是重新控制。除了控制ViewState的使用,ASP.NET使程序员自己的数据添加到ViewState中,这样他们就可以保存页面调用的数据。
你可能会问,然后控件使用ViewState保存在ViewState中的究竟呢?我决定接受挑战,并显示保存在视图状态数据和数据,这些控件保留所有控件创建一个观众。
有四个主要的方法,参与处理页面级别的ViewState。 SavePageStateToPersistenceMedium和LoadPageStateFromPersistenceMedium方法负责保存/加载ViewState来持久介质(默认的持久化介质是一个隐藏字段)/。 LoadViewState和SaveViewState方法,实际处理的数据,最终加载/保存到持久性媒体。由于ViewState的处理控制类LoadViewStateRecursive SaveViewStateRecursive方法的一部分,呼吁LoadViewState和SaveViewState方法来处理页面控件的ViewState递归。
如果将覆盖页SavePageStateToPersistenceMedium方法和检查唯一的参数传递到SavePageStateToPersistenceMedium,你会看到这个参数保存对象树。 "树",你会看到三胞胎,对和数组。所有这些容器类是完全用于存储页面和控件的ViewState。三胞胎类的三个对象和双组成,正如它的名字会建议,两个。这些类的每个对象可以是另一个三联,对ArrayList中,阵列和每一个他们可能包含其他对象等。三联,对ArrayList中,数组也可能包含字符串和基本类型。 ASP.NET使用LosFormatter类序列化到一个隐藏的输入(__VIEWSTATE)发送到客户端文本中的ViewState的树。
在谷歌快速搜索结束了与观众只显示所有三胞胎,对ArrayList中,阵列和原始类型的树视图。这很好,但我怎么能确定的控制,存储的数据和究竟他们存储在那些无尽的三元组,对ArrayList的树。具体的有关信息控制内ViewState和控制数据的数据必须在某处内的ViewState。这就是说,因为ASP.NET知道什么ViewState数据,它需要为每一个控制发送,我开始寻找在ViewState树数据。ASP.NET如何保存ViewState数据
显然有一些背后的大众的逻辑,它是这样的:
0。三胞胎
1第一(字符串) - 哈希值。
2。二(三联)
3(对)
4第一(ArrayList中) - 键。
5二(ArrayList中) - 值
6三(ArrayList中)
7 [X](三联)
8。二(ArrayList中)??数组保存在控制窗体的控件集合位置。
9三(ArrayList中) - 阵列,拥有从上层阵列的每一个控制的ViewState。
1号线:所有三重(0)开始。第一三重的第一个元素拥有一个字符串,它是一个哈希键的页面存储ViewState数据的控件层次结构。哈希键值通过视图状态,即使所有的页面控件EnableViewstae属性设置为false。
3号线:如果该项目拥有一双,这意味着用户要求保存在视图状态数据。如果用户没有保存任何值到ViewState,这个对​​象设置为null。
4号线:如果认为对3号线,这条线是第一对的对象是所有用户的ViewState键的ArrayList。
5号线:如果认为对3号线,这条线是第二对的对象是所有用户的ViewState值的ArrayList。
线6-7:第二个三元组的第三个对象持有控制权的数据保存在ViewState中的数据和数据,它保留了。第三个对象实际上是一个拥有控制和数据的三重对象的ArrayList。第三三重对象(ArrayList中)中的每个条目是另一个三重对象。这种内在的三重认为,在第二个和第三个对象有趣的数据。
8号线:在上述内部三的第二个对象是一个ArrayList。该数组中的每个条目保存的值是控制的HtmlForm对象(form标签)控件的集合位置。
9号线的第三个元素,这是一个ArrayList,以及内在的三重积分。该数组中的每个条目对应的控件的位置数组和实际持有,保存的数据是通过控制。这数组中的条目可以是一个单值或其他复杂的三重,双和的ArrayLists子树。
这就是为控制数据和其数据保存在ViewState树逻辑。在我们看一下如何使用这个逻辑控制显示页面的ViewState,也有其他的结论,我收集了有关控制数据结构。这些规则arent逻辑控制的公司。我的意思是,控制数据的规则通常被创建,但你不能预期的情况下,控制供应商可能会采取保存在ViewState中的数据。如果对??两个对象持有的ArrayList,他们通常表示键/值之间的ArrayLists,通常是第一个数组包含键和第二个数组保存的值的关系。如果三胞胎??第一个对象是原始值,而第二个和第三个数组保存的ArrayList,然后三联还拥有与键/值关系的ArrayList。通常的第一个对象(原始值)计数器保存在ListArrays元素。正如上面描述的,第二次和第三次的ArrayLists按住键/值数据。有情景三重拥有在第二次和第三次对象的ArrayList的第一个对象设置为null。这些阵列按住键/值数据。如果三联的第一个对象是原始类型,它通常拥有第二个和第三个对象中的元素数量的数据。创建ViewState的浏览器
我有一个单独的类(ViewStateViewer)内实施我的简单的查看器,所以你可以激活从每一页。所有你需要的是简单地调用ViewStateViewer的单一的公共方法(GetPageControlsViewState)。使用HtmlGenericControl,GetPageControlsViewState会使页面树,用户定义的控件的ViewState。最终,它看起来像在文章的顶部的形象。
阅读器类包含几个私有方法是递归解析树中的对象和作为树中的数据显示,他们确实是很容易遵循。有趣的部分进入GetPageControlsViewState方法,其中包含的页面,用户和controls.public无效GetPageControlsViewState(保存ViewState数据从逻辑){
将page.System.Web.UI.HtmlControls.HtmlGenericControl VSHtml渲染=新创建一个新树数据HtmlGenericControl System.Web.UI.HtmlControls.HtmlGenericControl();
检查当前请求保存在隐藏字段__VIEWSTATE的请求Form集合通过检查回发数据。我使用Page对象,以使此代码未绑定任何Page.if HttpContext.Current.Handler(((页)HttpContext.Current.Handler)的Request.Form [quot; __VIEWSTATEquot;]!= NULL){
获取字符串保存ViewState和反序列化到一个object.string vsInput =((页)HttpContext.Current.Handler)的Request.Form的序列化的数据 ["; __VIEWSTATEquot;]替换("\ nquot;,"; quot;)替换("\ rquot;,"quot;); 新LosFormatter对象。vsObject =()反序列化(vsInput);
获取页的ViewState是很容易的。它总是第一个元素的第一个Triplet.VSHtml.InnerHtml = quot; LT; BGT;数据:LT / BGT; LT; brgt; quot;ParseViewState(((三重)vsObject)首先,1);
检查,如果用户通过测试,如果第二个对象是一对对象类型添加自定义ViewState值。如果是这样,然后从对对象,并在整个循环的阵列键和值的数组的键/值对,并显示them.Triplet秒=(三联)((三重)vsObject)二。如果(Second.First是System.Web.UI.Pair){ System.Web.UI.Pair oPair =(System.Web.UI.Pair)Second.First; System.Collections.ArrayList oKeys = (System.Collections.ArrayList)oPair.First;&# 160; System.Collections.ArrayList椭圆= (System.Collections.ArrayList)oPair.Second; VSHtml.InnerHtml ="LT; brgt; LT; BGT;用户的ViewState:LT / BGT; LT; BRgt;"; 0; (I = 0; ILT; oKeys.Count;我) { &# 160;VSHtml.InnerHtml ="\ t键= quot; oKeys [我]的ToString()   ; ",值="椭圆形[我]的ToString()quot; LT; brgt;"; }}
ArrayList的items.ArrayList oArrObjectsAndData =(ArrayList中)Second.Third的第三个对象,通过和循环;(INT iObjAndData = 0; iObjAndDatalt; oArrObjectsAndData.Count; iObjAndData){
三重从ArrayList对象,然后投第二个(持有对象的代表)和第三(ViewState数据)对象ArrayList.Triplet oTripControls =(三联)oArrObjectsAndData [iObjAndData];ArrayList的oArrObjects =(ArrayList中)oTripControls.Second;ArrayList的oArrData =(ArrayList中)oTripControls.Third;
遍历对象的ArrayList。对于每一个对象:使用Controls集合中的控制地位,获取的HtmlForm控制它的ID;oArrData ArrayList的控制ViewState数据,并解析它。 (INT ICONT = 0; ICONT LT; oArrObjects.Count; ICONT) { &# 160; / /获得控件的ID ContID = GetForm()字符串对照组[(INT)oArrObjects [ICONT]编号; / /获取控件的ViewState。 三联oTrip =(三联)oArrData [ICONT]; VSHtml.InnerHtml ="LT; brgt; LT; BGT;"ContID quot;:LT / BGT; LT; BRgt; quot; &# 160; ParseViewState(oTrip,5); }}
设置HtmlGenericControl能见度,并把它添加到的解析形式collection.VSHtml.Visible = TRUE;Controls.Add被GetForm()(VSHtml);}}
如果你的结果看,你可以看到,每一个控制其存储的ViewState的逻辑。 ListBox中拥有三个两个数组。一个拥有显示值和其他持有相应的值。电网保存持有的一般信息(行数,页等)和每个单元的值和值类型的多个阵列。一个小的努力,您可以创建自定义查看器为每个服务器控制,检查的保留数据的控制类型和使用其自定义查看器。
使用此代码,可以很容易地看到哪些对象保存在ViewState中的数据和什么样的数据对象保留。如果你把它先行一步,您可以开发自定义的观众在一个更可读的的方式显示服务器控件视图状态。

回答

评论会员:游客 时间:2011/12/01
很好的例子,写得很好的文章imgsrc=http://www.orcode.com/upimg/2011_12_01_18_29_02_1.gif欢呼
!托里Cuturicu
评论会员:游客 时间:2011/12/01
。写得不好,最坏的解释,良好的内容
dotnethead
评论会员:游客 时间:2011/12/01
我测试过几个ViewState字符串,我总是-System.Web.UI.StateBag第二三重,第一对是alway空即使我存储在ViewState中的值,但其下的两个的ArrayLists充满。任何想法的,这可能是为什么?谢谢!"半本场比赛是百分之九十的精神。"-约吉贝拉
hlaford
评论会员:游客 时间:2011/12/01
这家伙不会出现递归操作。我已经有了一个控制在一个复杂的层次结构的转换,我只有一个输出控制(一个是LiteralControl不低于)。
迈克尔Freidgeim
评论会员:游客 时间:2011/12/01
我的网页上,我已经有了后再行空异常三联二(三联)=((三重)vsObject)第二;在GetPageControlsViewState(),因为对象vsObject.Second是空。它应该是额外的检查(null!=二){...{BR}}迈克尔
FruitBatInShades
评论会员:游客 时间:2011/12/01
在日文章S2}顶部没有形象绝对是PEBCAK!(键盘和椅子之间的问题存在)
整洁牛哥
评论会员:固定,谢谢! 时间:2011/12/01