`

对ViewState的解析

 
阅读更多
最近做项目,使用GridView进行数据编辑,怎么也获取不到用户输入的值,只能获取到目标TextBox和它之前绑定的值。

百思不得其解,后来在网上求助,发现原来是gridView的EnableViewState属性在作怪。下面,就来认识一下这个ViewState 。

什么是ViewState?

ViewState 用来跟踪和保存控件的状态信息。否则这些信息可能会丢失,原因可能是这些值不随着 form 回发,或者根本就不在 page 的 html 中。
ViewState 中保存着代码中改变的控件属性,通过代码绑定到控件的任何数据,以及由用户操作触发,回发的任何更改。
ViewState 还提供了一个状态包(StateBag), 这是一个特殊的集合或字典(collection or dictionary), 可以用来保存,通过一个 key 来恢复任意的对象或者值。

看看MSDN怎么说:


 // 摘要:
         //     获取状态信息的字典,这些信息使您可以在同一页的多个请求间保存和还原服务器控件的视图状态。
         //
         // 返回结果:
         //     包含服务器控件视图状态信息的 System.Web.UI.StateBag 类的实例。
         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
         [Browsable(false)]
         [WebSysDescription("Control_State")]
         protected virtual StateBag ViewState { get; }



ViewState不是什么?

1. ViewState 不是用来恢复回发的控件的值。
这个是通过匹配 form 中该控件的变量名而自动完成的。这个只对 Load 事件加载之前创建的控件有效。
2. ViewState 不会自动重新创建任何通过代码动态创建的控件。
3. 不是用来保存用户信息的。仅仅保存本页的控件状态,而不能在页面之间传递。

如何控制ViewState?

通过控件的EnableViewState属性来控制ViewState。下面来看看MSDN对这个属性的解释:

//
         // 摘要:
         //     获取或设置一个值,该值指示服务器控件是否向发出请求的客户端保持自己的视图状态以及它所包含的任何子控件的视图状态。
         //
         // 返回结果:
         //     如果服务器控件维护自己的视图状态,则为 true;否则为 false。默认值为 true。
         [WebSysDescription("Control_MaintainState")]
         [Themeable(false)]
         [DefaultValue(true)]
         [WebCategory("Behavior")]
         public virtual bool EnableViewState { get; set; }




注意这句话“如果服务器控件维护自己的视图状态,则为 true;否则为 false。默认值为 true。”

因为我没有修改原来的GridView的这个属性,所以怎么也没有获取到用户的输入。因为服务器始终保持着自己的视图状态!

ViewState 的工作原理

ViewState是一种机制,ASP.NET 使用这种机制来跟踪服务器控件状态值,否则这些值将不作为 HTTP 窗体的一部分而回传。例如,由 Label 控件显示的文本默认情况下就保存在 ViewState 中。作为开发人员,您可以绑定数据,或在首次加载该页面时仅对 Label 编程设置一次,在后续的回传中,该标签文本将自动从 ViewState 中重新填充。因此,除了可以减少繁琐的工作和代码外,ViewState 通常还可以减少数据库的往返次数。
  ViewState 确实没有什么神秘之处,它是由 ASP.NET 页面框架管理的一个隐藏的窗体字段。当 ASP.NET 执行某个页面时,该页面上的 ViewState 值和所有控件将被收集并格式化成一个编码字符串,然后被分配给隐藏窗体字段的值属性(即 <input type=hidden>)。由于隐藏窗体字段是发送到客户端的页面的一部分,所以 ViewState 值被临时存储在客户端的浏览器中。如果客户端选择将该页面回传给服务器,则 ViewState 字符串也将被回传。在上面的图 2 中可以看到 ViewState 窗体字段及其回传的值。
  回传后,ASP.NET 页面框架将解析 ViewState 字符串,并为该页面和各个控件填充 ViewState 属性。然后,控件再使用 ViewState 数据将自己重新恢复为以前的状态。

关于 ViewState 还有三个值得注意的小问题

如果要使用 ViewState,则在 ASPX 页面中必须有一个服务器端窗体标记 (<form runat=server>)。窗体字段是必需的,这样包含 ViewState 信息的隐藏字段才能回传给服务器。而且,该窗体还必须是服务器端的窗体,这样在服务器上执行该页面时,ASP.NET 页面框架才能添加隐藏的字段。
页面本身将 20 字节左右的信息保存在 ViewState 中,用于在回传时将 PostBack 数据和 ViewState 值分发给正确的控件。因此,即使该页面或应用程序禁用了 ViewState,仍可以在 ViewState 中看到少量的剩余字节。
在页面不回传的情况下,可以通过省略服务器端的 <form> 标记来去除页面中的 ViewState。

充分利用 ViewState

ViewState 为跨回传跟踪控件的状态提供了一条神奇的途径,因为它不使用服务器资源、不会超时,并且适用于任何浏览器。如果您要编写控件,那么肯定需要了解如何在控件中维护状态(英文)。
  开发人员在编写页面时同样可以按照几乎相同的方式来利用 ViewState,只是有时页面会包含不由控件存储的 UI 状态值。您可以跟踪 ViewState 中的值,使用的编程语法与会话和高速缓存的语法类似:
  请看下面的示例:要在 Web 页上显示一个项目列表,而每个用户需要不同的列表排序。项目列表是静态的,因此可以将这些页面绑定到相同的缓存数据集,而排序顺序只是用户特定的 UI 状态的一小部分。ViewState 非常适合于存储这种类型的值。代码如下:

<%@ Page Language="C#" %>
 <%@ Import Namespace="System.Data" %>
 <HTML>
     <HEAD>
         <title>用于页面 UI 状态值的 ViewState</title>
     </HEAD>
     <body>
         <form runat="server">
             <H3>
                 在 ViewState 中存储非控件状态
             </H3>
             <P>
                 此示例将一列静态数据的当前排序顺序存储在 ViewState 中。<br>
                 单击列标题中的链接,可按该字段排序数据。<br>
                 再次单击该链接,将按相反顺序排序。
                 <br><br><br>
                 <asp:datagrid id="DataGrid1" runat="server" OnSortCommand="SortGrid" 
                 BorderStyle="None" BorderWidth="1px" BorderColor="#CCCCCC" 
                 BackColor="White" CellPadding="5" AllowSorting="True">
                     <HeaderStyle Font-Bold="True" ForeColor="White" BackColor="#006699">
                     </HeaderStyle>
                 </asp:datagrid>
             </P>
         </form>
     </body>
 </HTML>
 <script runat="server">
 
    // 在 ViewState 中跟踪 SortField 属性
     string SortField {
 
        get {
             object o = ViewState["SortField"];
             if (o == null) {
                 return String.Empty;
             }
             return (string)o;
         }
         set {
             if (value == SortField) {
                 // 与当前排序文件相同,切换排序方向
                 SortAscending = !SortAscending;
             }
             ViewState["SortField"] = value;
         }
     }
     // 在 ViewState 中跟踪 SortAscending 属性
     bool SortAscending {
         get {
             object o = ViewState["SortAscending"];
             if (o == null) {
                 return true;
             }
             return (bool)o;
         }
         set {
             ViewState["SortAscending"] = value;
         }
     }
     void Page_Load(object sender, EventArgs e) {
         if (!Page.IsPostBack) {
             BindGrid();
         }
     }
     void BindGrid() {
         // 获取数据
         DataSet ds = new DataSet();
         ds.ReadXml(Server.MapPath("TestData.xml"));
         DataView dv = new DataView(ds.Tables[0]);
         // 应用排序过滤器和方向
         dv.Sort = SortField;
         if (!SortAscending) {
             dv.Sort += " DESC";
         }
         // 绑定网格
         DataGrid1.DataSource = dv;
         DataGrid1.DataBind();
    }
 
   void SortGrid(object sender, DataGridSortCommandEventArgs e) {
         DataGrid1.CurrentPageIndex = 0;
         SortField = e.SortExpression;
         BindGrid();
     }
 </script>

这是上面引用的testdata.xml文件的代码

<?xml version="1.0" standalone="yes"?>
 <NewDataSet>
   <Table>
     <pub_id>0736</pub_id>
     <pub_name>New Moon Books</pub_name>
     <city>Boston</city>
     <state>MA</state>
     <country>USA</country>
   </Table>
   <Table>
     <pub_id>0877</pub_id>
     <pub_name>Binnet &amp; Hardley</pub_name>
     <city>Washington</city>
     <state>DC</state>
     <country>USA</country>
   </Table>
   <Table>
     <pub_id>1389</pub_id>
     <pub_name>Algodata Infosystems</pub_name>
     <city>Berkeley</city>
     <state>CA</state>
     <country>USA</country>
   </Table>
   <Table>
     <pub_id>1622</pub_id>
     <pub_name>Five Lakes Publishing</pub_name>
     <city>Chicago</city>
     <state>IL</state>
     <country>USA</country>
   </Table>
   <Table>
     <pub_id>1756</pub_id>
     <pub_name>Ramona Publishers</pub_name>
     <city>Dallas</city>
     <state>TX</state>
     <country>USA</country>
   </Table>
   <Table>
     <pub_id>9901</pub_id>
     <pub_name>GGG&amp;G</pub_name>
     <city>Muenchen</city>
     <country>Germany</country>
   </Table>
   <Table>
     <pub_id>9952</pub_id>
     <pub_name>Scootney Books</pub_name>
     <city>New York</city>
     <state>NY</state>
     <country>USA</country>
   </Table>
   <Table>
     <pub_id>9999</pub_id>
     <pub_name>Lucerne Publishing</pub_name>
     <city>Paris</city>
     <country>France</country>
   </Table>
 </NewDataSet>
 


总结:

1:ViewState是一种机制,ASP.NET 使用这种机制来跟踪服务器控件状态值,否则这些值将不作为 HTTP 窗体的一部分而回传。这也就是为什么我没有获取

到用户输入的原因。

2:如果要使用 ViewState,则在 ASPX 页面中必须有一个服务器端窗体标记 (<form runat=server>)。

3:ViewState不使用服务器资源、不会超时,并且适用于任何浏览器,需要充分利用它。



以上信息来源于网络,不动之处,请查看原文:ViewState: All You Wanted to Know  和ViewState初探 。
分享到:
评论

相关推荐

    ViewState解析工具源码

    反编译前辈上传的ViewState解析工具。 想深入了解VIEWSTATE机制,可以下载源码来看看。

    asp.net页面中的viewstate内容解析器

    有些asp.net中使用viewstate,那里的内容是base64编码,此工具是把viewstate 内容给解析成原来内容,里面包括1.0,1.1,2.0三种版本的工具

    ViewState工具.rar

    查看ViewState数据,了解VIEWSTATE机制是一款程序猿常常用到的编程辅助工具,具有保存字符串信息的功能,该软件体积非常小的ViewState解析工具

    ViewStateDecoder_2.2

    解析ViewState内容 解析ViewState内容

    庖丁解牛:纵向切入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 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 对动态...

    WEB安全测试

    2.8 安装ViewState Decoder 36 2.9 安装cURL 36 2.10 安装Pornzilla 37 2.11 安装Cygwin 38 2.12 安装Nikto 2 39 2.13 安装Burp Suite 40 2.14 安装Apache HTTP Server 41 第3章 基本观察 43 3.1 查看网页的HTML源...

    ViewStateDecoder2.0

    aspx的神器,亲测可用,最近在做爬虫的时候用到的,解析.net数据的,资源网上可找,如果所需下载积分超过2,那没必要。。。。。。。。。。。。

    [完整][中文][WEB安全测试].(美)霍普.扫描版.pdf

    2.8 安装ViewState Decoder 36 2.9 安装cURL 36 2.10 安装Pornzilla 37 2.11 安装Cygwin 38 2.12 安装Nikto 2 39 2.13 安装Burp Suite 40 2.14 安装Apache HTTP Server 41 第3章 基本观察 43 3.1 查看网页的HTML源...

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

    这是一个基于多线程的邮件营销平台,核心技术包括网络爬虫、多线程、HTML解析、邮件发送、生产者消费者模式等。 注:以上三个案例,上课时会根据每个班的课堂反馈选择其中一个案例予以讲解学习。 7、如鹏网项目(9天...

    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...

    亮剑.NET深入体验与实战精要2

    本书集实用性、思想性、趣味性于一体,内容共分为技术基础总结、系统架构设计思想及项目实战解析三部分,随书所附光盘收录大量实例代码及独家披露的商业系统,供读者参考学习。 本书适合于.NET初、中级开发人员参考...

    亮剑.NET深入体验与实战精要3

    本书集实用性、思想性、趣味性于一体,内容共分为技术基础总结、系统架构设计思想及项目实战解析三部分,随书所附光盘收录大量实例代码及独家披露的商业系统,供读者参考学习。 本书适合于.NET初、中级开发人员参考...

    商用版本文本编辑器DotNetTextBoxV6.0.8Source 源码

    3)上传页面去掉所有input隐藏属性储存参数,改用ViewState储存,并加入ViewState的防改措施。 2009/07/05 Version 6.0.9 For VS2005/2008 Updates: 1)修正插入表格后在表格单元格插入内容会插到另一个单元格的BUG。...

    ExtAspNet_v2.3.2_dll

    目标是创建没有ViewState,没有JavaScript,没有CSS,没有UpdatePanel,没有WebServices的Web应用程序。 支持的浏览器: IE 7.0+, Firefox 3.0+, Chrome 2.0+, Opera 9.5+, Safari 3.0+ 注:ExtAspNet基于一些开源...

    ExtAspNet v2.2.1 (2009-4-1) 值得一看

    -尽管TabStrip, From, Tree, Accordion继承了Items属性,但是你并不能对其设置(此时Items是只读的). -这将会影响所有的aspx页面,一定要将工具条(Toolbars)和Items区分开来。 -祝你生日快乐 - 小师妹妹。 ...

    C#编程经验技巧宝典

    10 &lt;br&gt;0023 如何添加引用第3方控件 11 &lt;br&gt;0024 如何生成DLL文件 11 &lt;br&gt;0025 如何使用不安全代码 11 &lt;br&gt;第2章 语言基础 13 &lt;br&gt;2.1 注释 14 &lt;br&gt;0026 如何对代码进行注释 14 ...

Global site tag (gtag.js) - Google Analytics