`
az7772010
  • 浏览: 204059 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

viewstate原理

 
阅读更多

ASP.NET页面状态管理——ViewState的使用<wbr><wbr></wbr></wbr>

2010-03-03 19:49:59|<wbr><wbr>分类:</wbr></wbr> .net技术 |<wbr><wbr>标签:</wbr></wbr> |字号<wbr></wbr>订阅

ASP.NET ViewState设计目的是为了持久化当前页面中的对象的状态,以便下次在页面回发(Postback)后能够还原页面的状态。那么有两点需要注意:

ViewState只在需要Postback的页面里才需要使用;
在1前提之下,只有初始状态值被修改了的对象才需要持久化,即才需要使用ViewState。
1比较清楚,来谈第2点。以简单的Label控件为例,先来看一下它的Text属性的实现:

public virtual string Text
{
<wbr><wbr><wbr> get<br><wbr><wbr><wbr> {<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr> object obj2 = this.ViewState["Text"];<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr> if (obj2 != null)<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr> {<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> return (string) obj2;<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr> }<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr> return string.Empty;<br><wbr><wbr><wbr> }<br><wbr><wbr><wbr> set<br><wbr><wbr><wbr> {<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr> if (this.HasControls())<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr> {<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> this.Controls.Clear();<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr> }<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr> this.ViewState["Text"] = value;<br><wbr><wbr><wbr> }<br> }</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

很显然Text属性的后端都是以ViewState为存储介质的,ASP.NET服务器端控件的很多属性都是以类似方式实现的。假设一个页面default.aspx里只有一个Label控件, <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>,当访问该页面时,Label控件发送到客户端浏览器的代码大概为 <span id="xxx_Label1">Label</span>,同时ViewState中也保存了一份Text属性的值,形式大概为<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTgwMzg2ODMxMQ9kF<wbr>gJmD2QWAgIDD2QWAg......<br> 到目前位置,ViewState并没有发挥作用(这里谈论的都是在ViewState Enable的情况下),额外的保存了Text属性的值在这里是多余的。假设该页面还有一个Button控件,点击该按钮页面回发,那么在次过程中ViewState就发挥作用了么?分析一下该页面回发过程中Label控件生命周期的某些过程。首先,回发后,Label控件依然要经历初始化阶段(Init),这个阶段要创建一个Label控件的实例,同时设置其Text属性的,因为Text属性后端是以ViewState为存储介质的,所以就相当于向ViewState里添加了一个值,接下来,因为是回发过程,所以控件还要LoadViewState,即加载前次访问该控件的状态值,下面是Label控件的实现:</wbr>

protected override void LoadViewState(object savedState)

{

<wbr><wbr><wbr> if (savedState != null)</wbr></wbr></wbr>

<wbr><wbr><wbr> {</wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr> base.LoadViewState(savedState);</wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr> string text = (string) this.ViewState["Text"];</wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr> if (text != null)</wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr> {</wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> this.Text = text;</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr> }</wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr> }</wbr></wbr></wbr>

}
<wbr></wbr>


因为在前一访问过程中ViewState中所保存的Label的Text属性的状态值就是Label的初始值,所以导致了这里的LoadViewSate过程是多余的了,而且Init和LoadViewState两个过程对Text属性都赋了相同的值。由此可见,即使在页面回发中,如果不需要对属性的初始值进行修改,那么持久化属性的值(即使用ViewState)也是没有意义的。而且会带来多余的资源浪费,如两次对Text属性的赋值,以及增加了ViewSate的体积所带来的多余的网络传输。

那么,什么情况下使用ViewSate是值得的呢?我们先来把前面例子中两次访问的过程理一下:

第一次访问页面,Label控件初始化,设置Text属性的值,即向ViewState中添加了一个条目;
页面发送前(Render前),控件SaveViewState,即ViewSate中的值序列化,保存到一个隐藏域中;
页面发送,Label控件发送为相应的HTML标签,读取Text属性设置HTML标签的对象属性值,同时发送隐藏域及其值。对于Labe的Text属性来讲,相当于一份ViewState中的值发送了两份客户端拷贝;
第二次回发访问,Label控件初始化,设置Text属性的值,即向ViewState中添加了一个条目;
由于是回发访问,需经历LoadViewState过程,本例中即读取ViewState中Text属性在上一次访问中的状态值,而这个值实际上等于过程1中设置的值,读取的值再次设置Text属性,
第二次发送,重复过程2,3.
从过程1控件初始化,到过程6,第二次发送前SaveViewState,在这两个过程中间,如果不需改变Text属性的初始值,那么实际上就不需要使用ViewState。假设我们在过程1、2中间改变Text属性值,如在Page_Load中如此:

<wbr>protected void Page_Loadt(object sender, EventArgs e)<br><wbr>{<br><wbr> if (!IsPostBack)<br><wbr> {<br><wbr><wbr> Label1.Text = "Change Label's value";<br><wbr> }<br><wbr>}</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr>那么,尽管在回发时不能执行Label1.Text = "Change Label's value";语句,但由于ViewState的作用,第一次访问设置的值,在第二次回发访问后仍然会存在,即Label的Text属性值为”Change Label's value“,而不是其初始值“Label”。这种情况下才是ViewState的用武之地。注意!IsPostBack的使用,否则你只是每次访问都进行赋值而已,并没有利用ViewState的好处。</wbr>

由此,可以得出,在满足前面所述的两个条件时才应该使用ViewState。那么在现实应用中同时满足以上两个条件的情况下多么,也就是说我们需要使用ViewSate的时候多么?

很显然,满足这两个条件最大宗的情况就是数据绑定。而我认为ViewState的设计目的主要就是为了将必要的信息持久化在页面中,避免在两次访问中(确切的说不只两次,而是所有的回发访问中)都要进行数据绑定(而每次数据绑定往往意味着一次次的数据库访问)。例如用GridView绑定DataSource控件展现一个类表数据,在ViewSate Enable的情况下,页面第一次加载时进行数据绑定,在随后的回发访问中,如果仍是访问当前数据视图,即没有进行分页、排序操作等,DataSource不会再进行数据绑定,因为所有的信息都可以从ViewSate中获取,不需要再次访问数据库再次绑定数据控件了。而如果你将ViewState Disable掉,那么每次访问则都需要进行数据绑定了(可以通过SqlProfiler来捕捉SqlDataSource在两种情况下对数据库的访问情况)。这个场景可能最能说明ViewSate的设计初衷了。

然而在实际的应用中,上面的这种场景多么?在数据列表页面,往往没有除了分页排序等之外的回发操作(你放Grid的页面里有回发的按钮么?),而分页,排序操作所引起的回发显然是需要数据再绑定的。如果是这种场景,那么你就应该把这个页面或者把这个Grid的EnableView属性设为false了。这里讲点题外话,有人会说如果设成false,那Grid的分页信息、排序信息怎么传递给后续的回发访问呢?其实在ASP.NET 2.0中控件的状态管理被分为了两部分view state和control state。两者的区别是什么呢,那ASP.NET 1.x中的DataGrid控件来说,DataGrid的所有状态信息都保存在view state当中,但是这些信息所符合的view state应用场景是矛盾的,比如你的页面没有回发操作,你不必把所有数据缓存到view state里,这时你会把datagrid的enableviewstate属性设为false,但当你这么做后,datagrid的另一些功能如翻页、排序,就没法使用了,因为翻页排序的状态信息也是保存在view state中的,如pageindex、sort asc/desc等。就类似于这种问题,ASP.NET 2.0中又引入了control state,control state的存储方式与view state相同,不同的地方在于它不会被disable掉。这样control state用来存储那些控件的功能性的,必需的信息。比如即使GridView的view state被禁止了,它的分页,排序等信息还是仍然正常工作的。

ASP.NET的一些设计,如整个页面一个form元素,以及本文谈到的view state的使用等,只是在宏观上,概率统计上能达到节约成本,提高效率的目的。但是具体到一个Web程序, 一个应用场景,一个页面,甚至是一个控件,如果你知到它们背后的东西,你就会更好更正确的去实现它或使用它。

<wbr></wbr>

=========================================================

2007-08-28 14:16 369人阅读 评论(0) 收藏 举报

<wbr>今天遇到了这样个问题,令我迷惑了很久,查了查资料才发现它的奥妙之处</wbr>

问题如下:

-------------------------------------------------------------------------------------------------------------------------------------------------------

为什么TextBox的EnableViewState已经设置成了FALSE,Textbox在回发之后还是可以保存Textbox中的输入的内容?

-------------------------------------------------------------------------------------------------------------------------------------------------------

原因解答:

-------------------------------------------------------------------------------------------------------------------------------------------------------

一、EnableViewState优先级别: <wbr><br><wbr> 全局配置 <wbr> &lt; <wbr> 程序 &lt; <wbr> 页&lt; <wbr> 控件 <wbr><br><wbr><wbr><br><wbr> 注意:下列服务器控件不能禁止ViewState <wbr><br><wbr><wbr><br><wbr> Textbox <wbr><wbr><br><wbr> Checkbox <wbr><br><wbr> Checkbox <wbr> List <wbr><br><wbr> RadioButtonList <wbr><br><wbr> 上面控件的状态通过IPostBackEventHandler <wbr> 和 <wbr> IPostBackDataHandler接口处理,而不是ViewState的机制,所以EnableViewState没有效果。<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

二、经常需要变值的控件,回发的数据并不依赖于ViewState。回发的控件都实现了IPostBackDataHandler接口,该接口的LoadPostData方法中,会对返回的值和ViewState中的值进行判断,如果改变了的话,调用RaisePostDataChangedEven<wbr>t方法触发相应的事件(对于TextBox来说就是TextChanged事件)。LoadPostData中如果返回的值和ViewState中的值不同的话,将把TextBox的值设置成返回的值。这就是你看到的结果。<br> -------------------------------------------------------------------------------------------------------------------------------------------------------</wbr>

扩展:

在ASP.Net中对各个WebForm控件引入以前没有的EnableViewState属性。这个属性究竟有什么用。我们知道对于WebForm而言,其代码是在服务器端的,以处理客户端的请求。当用户通过浏览器浏览网页的时候,会对网页进行某些操作,比如打开新链接,或单击某个按钮。在ASP中,这些是通过脚本语言对其进行处理,之后再传递给服务器端。但是在ASP.NET下,由于采用了code behind技术,在coding的时候,通常是将以前客户端完成的工作放到了服务器端。

那么,服务器是怎么知道客户的操作的呢?比如我在文本框输入的内容,或者单击了登录按钮,服务器端是怎样得到这些信息的呢?因为没有这些信息,服务器端就无法响应客户的请求。原理就是ASP.NET引用了viewstate的机制。在服务器端保存了网页各个控件及页面的状态,这其中包括各个控件在页面上的布局,和他们各自的属性。这些值就保存在ViewState下。我们可以观察Aspx页面的html源代码,假设这个页面上有一个button按钮,和一个listBox控件,html文件如下:

<input type="hidden" name="__VIEWSTATE" value="dDwzODYzNDM5NTU7Oz7FvviJ<wbr>bq45bDa7QJaumIiOhZ8mOQ==" /&gt;</wbr>

<wbr>&lt;input type="submit" name="Button1" value="Button" id="Button1" style="height:40px;width:96px;Z-INDEX: 101; LEFT: 200px; POSITION: absolute; TOP: 240px" /&gt;<br><wbr>&lt;select name="ListBox1" size="4" id="ListBox1" style="width:152px;Z-INDEX: 102; LEFT: 176px; POSITION: absolute; TOP: 120px"&gt;&lt;/select&gt;<br></wbr></wbr>

我们它的不同之处,一是少了以前所必须响应客户端事件的脚本语言,一是多了一个名为”_VIEWSTATE”的属性。其值是一长串字符。类型为“hidden”。这个值记录的就是各个控件和页面的状态信息。当用户对页面进行相关操作的时候,状态值发生改变,并将改变的值传递给服务器端。服务器端在比较改变后的状态值和初始值之间的区别,以响应具体的请求。

一旦页面的控件很多,这种频繁的传递控件状态值对网络的消耗是很大的,因此,ASP.Net提供了EnableViewState属性,系统默认的值为true。当设置为true时,在传递状态值时就包括该控件;如果设置为false,则传递状态值时则不包括它。既然状态值不包括该控件,则客户端对它进行的操作,服务器端是不响应的。

我们可以做个实验,在Button1_Click事件中,编写代码:

ListBox.Items.Add(”客户端点击按钮一次!”);

此时运行该应用程序,单击网页上的按钮,在ListBox中会添加内容,不断地单击,内容则不断添加。如果我们将ListBox的EnableViewState属性改为false时,不断单击按钮,则只能添加一次。

这样有什么好处呢?如果我们在开发Web应用程序时,某些控件是不需要接受用户的操作或只需要接受一次操作的时候,我们可以将这些控件的EnableViewState属性改为false,这样可以优化我们的程序,提高网络访问的速度。

分享到:
评论

相关推荐

    .net 中viewstate的原理和使用

    如果在客户端和服务器段保持往返的状态,在.net中通过加入一个隐藏控件_ViewState来实现的,这些状态的保持不需要程序员来控制,节省了程序员的精力。但是如果大量使用viewstate会影响性能,例如页面中控件过多,那么...

    asp.net中ViewState的用法详解

    本文给大家介绍asp.net中viewstate的用法,涉及到viewstate的原理、用法、与session的对比等方面的知识,对viewstate用法感兴趣的朋友一起看看吧

    9.基于THB7128步进电机驱动板原理图+PCB源文件(直接拿来可以用)

    9.基于THB7128步进电机驱动板原理图+PCB源文件(直接拿来可以用)9.基于THB7128步进电机驱动板原理图+PCB源文件(直接拿来可以用)9.基于THB7128步进电机驱动板原理图+PCB源文件(直接拿来可以用)9.基于THB7128步进...

    24l01设计软硬件技术资料包括原理图PCB、软件源码、技术文档、调试经验等.zip

    NRF24L01参考PCB.pcbdoc_viewstate NRF24l01无线232通信.rar nRF24L01无线模块6个接收通道.zip NRF24L01模块MEGA16测试程序.rar nrf24l01硬件spi参考.rar nrf24L01编程心得1.txt nrf24L01编程心得1很牛逼的.txt ...

    asp.net2.0系列教程第5章_第2节

    第5章第二节ViewState HiddenField的原理和应用(续)Cookie的原理和应用

    asp.net2.0系列教程第5章_第1节

    5章_第1节 第一节ViewState HiddenField的原理和应用

    ASP.NET简答题,doc文档

    1、什么是ASP.NET? 2、RSS是什么?做什么用的? 3、Cookie分哪两种?分别描述一下 4、介绍一下ViewState的原理?如何使用 5、介绍一下HiddenField与ViewState的区别?各自在什么场所使用 ....

    Altium Designer常用库文件

    Altium Designer常用库文件,资源小巧,但浓缩的是精华,不冗余,常用的、必要的器件原理图库和PCB库均有。

    不可或缺的ASP.NET内置对象

    事件四、ViewState对象保存数据取出数据总结ViewState的本质五、Session对象1.Session的原理2.属性3.方法4.用途六、Cookie对象1.Cookie的特点2.Cookie的创建3.属性4.方法5.Cookies工作原理图七、Application对象1....

    DoNet学习-WebForm视频教程(30集)

    资源名称:DoNet学习-WebForm视频教程(30集)资源目录:【】7ab37727cfeaf3ac0e59eff10c664831【】WebForm状态_上午1复习页面生命周期复习Transfer【】WebForm状态_上午2ViewState使用以及原理【】WebForm状态_上午...

    BoardGameList-CleanArchi:示例代码探索SwiftUI和使用Clean Architecture结合

    查看触发器(带有用户输入或副作用) Interactor Interactor使用Workers ,存储库和更新ViewState ViewState更新(通过绑定) View原料药该项目使用开放的API 场景我们的应用程序包含2个场景。游戏清单第一个场景是...

    .NET下实现数字和字符相混合的验证码实例

     言归正传,关于验证码的原理,我就不多说了,大家可以参见其他文章,文末附有完整的实例代码,里面有详细的注释,你可以跳过解说文字,直接使用 首先,我要简要说说Session和ViewState的用法,因为后面会用到它 把数据...

    grab-classes

    中大南方教务系统抢课原理:构造POST请求,循环刷包。环境要求jdk 1.8及以上,操作系统不限。使用方法1.自行下载源码编译运行。2.下载根目录下的grab.jar,在cmd内执行 java -jar grab.jar运行。配置请求参数在C盘/...

    史上最好传智播客就业班.net培训教程60G 不下会后悔

    而是通过ashx的模式开发原始的动态网站,让学员明白“请求—处理—响应模型”、“Http协议、Http无状态”、“c#代码渲染生成浏览器端JavaScript”、“ViewState的作用”、“Session的原理”等这些基本而又重要的原理...

    庖丁解牛纵向切入ASP.NET 3.5控件和组件开发技术.pdf

    6.4.1 在禁用视图状态的情况下仍然使用viewstate对象221 6.4.2 istatemanager接口仍然可以在控件状态中使用223 6.4.3 视图状态和控件状态组合使用规则225 6.5 加密页面状态225 6.6 清除页面状态226 6.7 对动态...

    庖丁解牛:纵向切入ASP.NET 3.5控件和组件开发技术

    6.4.1 在禁用视图状态的情况下仍然使用viewstate对象 221 6.4.2 istatemanager接口仍然可以在控件状态中使用 223 6.4.3 视图状态和控件状态组合使用规则 225 6.5 加密页面状态 225 6.6 清除页面状态 226 6.7 对...

    庖丁解牛 纵向切入ASP.NET 3.5控件和组件开发 part1

    6.4.1 在禁用视图状态的情况下仍然使用viewstate对象 221 6.4.2 istatemanager接口仍然可以在控件状态中使用 223 6.4.3 视图状态和控件状态组合使用规则 225 6.5 加密页面状态 225 6.6 清除页面状态 226 6.7 对...

    庖丁解牛 纵向切入ASP.NET 3.5控件和组件开发 part2

    6.4.1 在禁用视图状态的情况下仍然使用viewstate对象 221 6.4.2 istatemanager接口仍然可以在控件状态中使用 223 6.4.3 视图状态和控件状态组合使用规则 225 6.5 加密页面状态 225 6.6 清除页面状态 226 6.7 对...

    asp.net知识库

    Server Side ViewState 在服务器端存贮ViewState (ASP.NET 2.0) VS2005 ASP.NET本地化学习笔记&感受 在自定义Server Control中捆绑JS文件 Step by Step 深度解析Asp.Net2.0中的Callback机制 使用 Web 标准生成 ASP...

    asp.net教学讲义

    1.2.5 WEB窗体工作原理 11 1.3 ASP.NET 页的结构 12 1.3.1 @Page指令 13 1.3.2 ASP.NET的服务器端脚本 14 1.3.3 服务器端脚本示例: 14 1.3.4 后台编码模型 15 1.4 Page事件(页面事件) 15 1.4.1 Page类 15 1.4.2 ...

Global site tag (gtag.js) - Google Analytics