`

ASP.NET ViewState使用实例介绍

阅读更多

 

ASP.NET ViewState使用实例介绍

摘自:http://www.delphibbs.com/keylife/iblog_show.asp?xid=31099

1. ViewState的工作原理

    ViewState是由ASP.NET页面框架管理的一个隐藏的窗体字段。当ASP.NET执行某个页面时,该页面上的ViewState值和所有控件将被收集并给和格式化成一个编码字符串,然后分配给隐藏窗体字段的值属性(即<input type=”hidden”>)。由于隐藏窗体字段是发送到客户端的页面的一部分,所以ViewState值被临时存储在客户端的浏览器中。如果客户端选择该页面回传给服务器,则ViewState字符串也将被回传。回传后,ASP.NET页面框架将解析ViewState字符串,并为该页面和各个控件填充ViewState属性。然后,控件再使用ViewState数据将自己重新恢复为以前的状态。

2.  关于ViewState要注意的问题

1、如果要使用ViewState,则在ASPX页面中必须有一个服务器端窗体标记(<form     runat="server">)。窗体字段是必需的,这样包含ViewState信息的隐藏字段才能回传给服务 器。而且,该窗体还必须是服务器端的窗体,这样在服务器上执行该页面时,ASP.NET页面  框架才能添加隐藏的字段。

2、页面本身将20字节左右的信息保存在ViewState中,用于在回传时将PostBack数据和ViewState值分发给正确的控件。因此,即使该页面或应用程序禁用了ViewState,仍可以在ViewState中看到少量的剩余字节。

3、在页面不会传得情况下,可以通过省略服务器端的<form>标记来去掉页面中的ViewState。

3.  充分利用ViewState

ViewState为跨回传跟踪控件的状态提供了一条神奇的路径,因为它不使用服务器资源、不会超时,并且适用任何浏览器。

ViewState的创建和使用:

     //保存在ViewState中

     ViewState["SortOrder"] = "DESC";

     //从ViewState中读取

 string sortOrder = (string)ViewState["SortOrder"];

代码如下:

Default3.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default3.aspx.cs" Inherits="Default3" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>无标题页</title>

</head>

<body>

    <form id="form1" runat="server">

        <h3>

            在 ViewState 中存储非控件状态

        </h3>

        <p>

            此示例将一列静态数据的当前排序顺序存储在 ViewState 中。<br />

            单击列标题中的链接,可按该字段排序数据。<br />

            再次单击该链接,将按相反顺序排序。</p>

        <p>

            <asp:GridView ID="GridView1" runat="server" BackColor="White" BorderColor="#3366CC"

                BorderStyle="None" BorderWidth="1px" CellPadding="4" AllowSorting="True" OnSorting="GridView1_Sorting">

                <FooterStyle BackColor="#99CCCC" ForeColor="#003399" />

                <RowStyle BackColor="White" ForeColor="#003399" />

                <SelectedRowStyle BackColor="#009999" Font-Bold="True" ForeColor="#CCFF99" />
软件开发网 www.mscto.com



                <PagerStyle BackColor="#99CCCC" ForeColor="#003399" HorizontalAlign="Left" />

                <HeaderStyle BackColor="#003399" Font-Bold="True" ForeColor="#CCCCFF" />

            </asp:GridView>

            &nbsp;</p>

    </form>

</body>

</html>

 

Default3.aspx.cs

using System;

using System.Data;

using System.Configuration;

using System.Collections;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls; 软件开发网 www.mscto.com

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

 

public partial class Default3 : System.Web.UI.Page

{

      protected void Page_Load(object sender, EventArgs e)

      {

           if (!this.IsPostBack)

           {

            BindGrid();

           }

       }

 

      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 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";

        }

 

        // 绑定网格

        this.GridView1.DataSource = dv;

        this.GridView1.DataBind();

    }

    protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)

    {

        this.GridView1.PageIndex = 0;

        SortField = e.SortExpression;

        BindGrid();

    }

}

Testdata.xml

<?xml version="1.0" encoding="utf-8" ?>

<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> 软件开发网 www.mscto.com

    <pub_name>Lucerne Publishing</pub_name>

    <city>Paris</city>

    <country>France</country>

  </Table>

</NewDataSet>

4.  选择会话状态还是ViewState?

在某些情况下,状态值保存在ViewState中部是最佳选择,最常用的替代方法就是会话状态,它通常更适用于:

1、大量的数据:由于 ViewState 增加了发送到浏览器的页面的大小(HTML 有效负载),   同时也增加了回传的窗体的大小,因此不适合存储大量数据。

2、未在UI中显示的安全数据:尽管ViewState数据已被编码,并且可以选择对其进行加密,但始终不将数据发送到客户端才是最安全的,因此,会话是更安全的选择。(由于数据库学要额外的凭据进行验证,因此将数据存储在数据库中会更安全。可以添加SSL以获得更安全的链接。)但是,如果在UI中已经显示了该专用数据,那么您应该已经确认了链接的安全性。在这种情况下,将同样的值放入ViewState不会降低安全性。

3、尚未序列化到ViewState中的对象,如DataSet。ViewState序列化程序只为一小部分常用的对象类型进行了优化,其他可序列化的类型或许可以保留在ViewState中,但速度会变慢,并会生成一个非常大的ViewState。



比较项
   

会话状态
   

ViewState

是否适用服务器资源
   


   



是否超时
   

是,20分钟后(默认)
   



是否存储所有.NET类型
   


   

否,仅支持:sting、int、bool、Array、ArrayList、Hashtable和自定义TypeConverter

是否增加“HTML有效负担”
   


   



 

5.  使用ViewState获得最佳性能

使用ViewState时,每个对象都必须先序列化到ViewState中,然后再通过回传进行反序列化,因此使用ViewState并非是没有代价的。但是,如果遵循某些简单的原则对ViewState的成本加以控制,并通常不会产生明显的性能影响。

1、  在不需要时禁用ViewState。

2、  使用优化过的ViewState序列化程序,上面列出的类型具有专门的序列化程序,这些程序运行速度很快,并已经过优化,可以生成很小的ViewState。如果要序列化一个未在上面列出的类型,可以创建一个自定义TypeConverter来显著提高它的性能。


3、  尽量减少使用对象,如果可能,尽量减少放入ViewState中的对象的数目。例如,不要使用尔维数组(名称/值,其对象的数目与数组的长度一样多),而应适用二个字符串数组(只有两个对象)。但是,在将二个已知类型存储在ViewState中之前,在这两者之间转换不会获得不会获得任何性能提高,因为这样做实际上相当于付出了两次转换的代价。

6.  减少使用ViewState

默认情况下,ViewState将被启用,并且是由每个控件(而非页面开发人员)来决定存储在viewState中的内容。有时,这一信息对应程序并没有什么用处。尽管也没什么害处,但却会明显增加发送到浏览器的页面的大小。因此如果不需要使用viewState,最好还是将它关闭,特别是当ViewState很大的时候。

可以基于每个控件、每个页面或每个应用程序来关闭ViewState。在以下情况下不再需要ViewState。

页面
   

控件

页面不回传给自身
   

处理的不是控件地事件

控件没有动态的或数据邦定的属性值(或对于每一个请求他们都设置在代码中)

关闭ViewState例子:

Default4.aspx



<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default4.aspx.cs" Inherits="Default4" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>减少页面的“HTML 有效负载”</title>

</head>

<body>

    <form id="form1" runat="server">

        <h3>

            通过禁用 ViewState 来减少页面的“HTML 有效负载”

        </h3>

        <p>



            <asp:GridView ID="GridView" runat="server" BackColor="White" BorderColor="#3366CC" BorderStyle="None" BorderWidth="1px" CellPadding="4" EnableViewState="False">

                <FooterStyle BackColor="#99CCCC" ForeColor="#003399" />

                <RowStyle BackColor="White" ForeColor="#003399" />

                <SelectedRowStyle BackColor="#009999" Font-Bold="True" ForeColor="#CCFF99" />

                <PagerStyle BackColor="#99CCCC" ForeColor="#003399" HorizontalAlign="Left" />

                <HeaderStyle BackColor="#003399" Font-Bold="True" ForeColor="#CCCCFF" />

           

            </asp:GridView>

        </p>

    </form>

</body>

</html>

Default4.aspx.cs

using System;

using System.Data;

using System.Configuration;

using System.Collections;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

 

public partial class Default4 : System.Web.UI.Page

{

    protected void Page_Load(object sender, EventArgs e)

    {

        DataSet ds = new DataSet();

        ds.ReadXml(Server.MapPath("testdata.xml"));

        this.GridView.DataSource = ds;

        this.GridView.DataBind();

    }

}

7.  禁用ViewState

在上述事例中,我通过将网络的EnableViewState属性设置为false禁用了ViewState。可以针对单个控件、整个页面或整个应用程序禁用ViewState,如下所示:

每个控件(在标记上)
   

<asp:GridView EnableViewState=”false”/>

在页面(在指令中)
   

<%@Page EnableViewState=”false”%>

每个应用程序(在web.config中)
   


<Pages EnableViewState=”false”/>

 

8.  使用ViewState更安全

由于ViewState没有被格式化为清晰的文本,某些人有时会认为它被加密了,其实并没有。相反,ViewState只是进行了Base64编码,以确保值在返回过程中不会发生变化,而且不考虑应用程序使用的相应/请求编码。可以向应用程序中添加2种ViewState安全级别:1、防篡改;2、加密。

1、  防篡改

尽管散列代码不能确保ViewState字段中实际数据的安全,但它能够显著降低有人通过ViewState骗过应用程序的可能性,即防止回传应用程序通常禁用输入的值。

可以通过设置EnableViewStateMac属性来显示ASP.NET向ViewState字段中追加一个散列代码:

<%@ Page EnableViewStateMac="true" %>

可以在页面级上设置EnableViewStateMac,也可以在应用程序级别上设置。在回传时,ASP.NET将为ViewState数据生成一个散列代码,并将其与存储在回传值中的散列代码进行比较。如果两处的散列代码不匹配,该ViewState数据将被丢弃,同时控件将恢复为原来的设置。

默认情况下,ASP.NET使用SHA1算法来生成ViewState散列代码,此外,也可以通过在machine.config文件中设置<machineKey>来选择MD5算法,如下所示:<machineKey validation="MD5" />
软件开发网 www.mscto.com



2、  加密

    可以使用加密来保护ViewState字段中的实际数据值。首先,必须设置:EnableViewState=”true”,然后,将machineKey validation类型设置为3DES。这个指示ASP.NET使用Triple DES对称加密算法来加密ViewState值。<machineKey validation=”3DES”/>

9.  Web领域中的ViewState安全性

默认情况下,ASP.NET将创建一个随机的验证钥匙,并存储在每个服务器的本地安全授权(LSA)中。要验证在另一台服务器上创建的ViewState字段,两台服务器的validationKey必须设置为相同的值。如果通过上述方式之一,对运行Web领域配置中的应用程序进行ViewState安全设置,则需要为所有服务器提供一个唯一的、共享的验证密钥。

Default5.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default5.aspx.cs" Inherits="Default5" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">



 

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>无标题页</title>

</head>

<body>

    <form id="form1" runat="server">

        <h3>生成随机加密密钥</h3>

        <p>

            <asp:RadioButtonList ID="RadioButtonList" runat="server" RepeatDirection="horizontal">

                <asp:ListItem Value="40">40-byte</asp:ListItem>

                <asp:ListItem Value="128" Selected="True">128-byte</asp:ListItem>
软件开发网 www.mscto.com


            </asp:RadioButtonList>

            <asp:Button ID="Button" runat="server" Text="生成密钥" OnClick="Button_Click" />

        </p>

        <p>

            <asp:TextBox ID="TextBox" runat="server" TextMode="multiLine" Rows="10" Columns="70" BackColor="#EEEEEE" EnableViewState="false">

                复制并粘贴生成的结果

            </asp:TextBox>

        </p>

    </form>


</body>

</html>

Default5.aspx.cs

using System;

using System.Data;

using System.Configuration;

using System.Collections;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using System.Security.Cryptography;

using System.Text;

 

public partial class Default5 : System.Web.UI.Page

{

    protected void Page_Load(object sender, EventArgs e)

    {

 

    }

    protected void Button_Click(object sender, EventArgs e)

    {

        int keylength = Int32.Parse(this.RadioButtonList.SelectedItem.Value);


        //在此处放入用于初始化页面的用户代码

        byte[] buff = new byte[keylength / 2];

        RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

        //该数组已使用密码增强的随机字节进行填充

        rng.GetBytes(buff);

        StringBuilder sb = new StringBuilder(keylength);

        for (int i = 0; i < buff.Length; i++)

        {

            sb.Append(string.Format("{0:X2}", buff[i]));

        }

        this.TextBox.Text = sb.ToString();

    }


}

 

10.   总结:

ASP.NET ViewState是一种新的状态服务,可供开发人员基于每个用户来跟踪UI状态。ViewState是在一个隐藏的窗体字段中来回传递状态,并将它直接应用于页面处理框架中。但效果却非常好,在基于Web的窗体中只需要编写并维护很少的代码。

分享到:
评论

相关推荐

    ASP.NET ViewState 初探

    由于Web的本质是无状态的,每次用户请求页面时,服务器都会创建一个新的页面实例,而ASP.NET页面也不例外。这就意味着在用户交互过程中,如表单提交,服务器无法记住之前的页面状态,除非开发人员采取措施来保存和...

    asp.net网站实例

    学习如何使用ASP.NET的身份验证和授权机制,以及防止SQL注入和跨站脚本攻击。 8. **用户体验**:理解CSS和JavaScript的使用,为投票系统提供良好的界面设计和交互体验。可能还会涉及到AJAX技术,以实现无刷新的投票...

    ASP.NET 实例开发全教程 源码

    4. **状态管理**:ASP.NET通过视图状态(ViewState)、隐藏字段、Cookie和Session等方式维护页面或用户的状态,这对于构建动态、交互性强的Web应用非常重要。 5. **路由**:虽然Web Forms主要基于PostBack模型,但...

    asp.net电子相册实例

    ASP.NET电子相册实例是一个基于ASP.NET技术构建的在线照片管理和展示系统,它提供了一个方便的方式来存储、组织和分享个人或集体的照片集。这个实例深入浅出地展示了如何利用ASP.NET框架来创建一个功能完善的相册...

    ASP.NET专业项目实例开发(修订版)-高健_源代码

    在本书的源代码中,我们可以找到多个**项目实例** ,这些实例涵盖了ASP.NET开发的多个方面,如用户界面设计、数据库交互、服务器控件使用、数据验证、会话管理、缓存优化、安全性控制等。通过对这些实例的学习,读者...

    ASP.net网站设计实例

    ### ASP.NET网站设计实例知识点详解 #### 一、ASP.NET简介 ASP.NET是Microsoft开发的一种服务器端脚本环境,用于创建动态网页。它基于.NET框架,可以使用多种编程语言(如C#、VB.NET等)来编写代码。ASP.NET提供了...

    ASP.NET 就业实例教程源码及 ppt

    本教程集合了ASP.NET的就业实例教程源码和相关的PPT,旨在帮助学习者深入理解并掌握ASP.NET的实际应用,提升其在就业市场中的竞争力。 首先,ASP.NET提供了多种开发模型,如Web Forms、MVC(Model-View-Controller...

    asp.net实例程序

    ASP.NET提供了多种状态管理机制,如ViewState、Session、Cookie和Application等,用于在不同请求之间保持页面或用户的状态。这些实例将演示如何使用这些机制来保存和恢复数据。 5. **页面间通信** 使用ASP.NET的...

    ASP.NET+ADO.NET项目开发实例

    9. **状态管理**:理解ASP.NET的状态管理机制,如ViewState、Session、Cookie和Application状态,以及何时选择合适的存储方式。 10. **安全性**:学习如何实现身份验证和授权,使用ASP.NET的身份验证服务和角色管理...

    ASP.NET 52个实例

    本资源"ASP.NET 52个实例"旨在通过一系列实践教程帮助开发者深入理解和掌握ASP.NET的核心概念和技术。 这些实例涵盖了多种常见的Web开发场景,例如用户注册和登录,这些都是任何Web应用程序的基础功能。在ASP.NET中...

    Asp.net 快速开发实例1.0 (C#)

    5. **表单验证**:介绍如何使用Asp.net的验证控件来确保用户输入的数据有效性和安全性。 6. **MVC模式**:如果实例涵盖,可能会讲解Asp.net MVC框架,它是Asp.net的一种轻量级、可测试的应用程序开发模型。 7. **...

    ASP.NET网站设计实例通3

    3. **服务器控件**:介绍ASP.NET提供的各种服务器控件(如Button、TextBox、GridView等),并演示如何在页面上使用这些控件进行数据输入、显示等操作。 4. **验证控件**:讲解如何使用ASP.NET内置的验证控件(如...

    ASP.NET网络系统实例两个

    本实例包括基础平台管理系统和在线帮助系统两个项目,旨在帮助开发者深入理解和实践ASP.NET 2.0与SQL Server结合的网络系统开发。 1. **基础平台管理系统**: 这个系统通常包含用户管理、角色管理、权限控制、数据...

    ASP.NET例子系列之ASP.NET 网站设计实例通 实例代码

    ASP.NET是微软公司推出的一种基于.NET Framework的Web应用程序框架,用于构建动态、数据驱动的网站。这个"ASP.NET 网站设计实例通 ...每一个实例都是一个宝贵的教材,帮助开发者从实践中学习,逐步精通ASP.NET的使用。

    asp.net源代码实例

    ASP.NET提供了多种状态管理机制,如ViewState、Session、Cookie等,用于在页面间或用户会话间保持数据。实例可能展示了如何使用这些状态管理技术,以实现动态交互和用户个性化体验。 4. **数据访问** ASP.NET可以...

    asp.net3.5项目实例之博客系统

    **ASP.NET 3.5博客系统项目实例详解** 在IT领域,ASP.NET 3.5是一种广泛使用的Web应用程序开发框架,由微软公司提供,它基于.NET Framework 3.5版本。本实例主要围绕如何利用ASP.NET 3.5构建一个功能完备的博客系统...

    ASP.NET管理系统 实例源码下载

    这个管理系统实例源码下载提供了深入理解ASP.NET技术及其在实际项目中的应用的一个绝佳机会。 1. **ASP.NET框架基础** ASP.NET是.NET Framework的一部分,它提供了丰富的功能和工具,简化了Web开发流程。通过使用...

    asp.net实例源代码合集

    这个"asp.net实例源代码合集"显然是一个包含多种ASP.NET应用场景的代码库,可能涵盖从基础到高级的各种技术。 在ASP.NET中,你可以了解到以下关键知识点: 1. **页面生命周期**:ASP.NET页面经历一系列的生命周期...

    ASP.NET 网站设计实例通

    【ASP.NET 网站设计实例通】 ASP.NET是由微软公司开发的一种用于构建Web应用程序的框架,它基于.NET Framework,提供了丰富的功能和高效的语言支持,如C#和VB.NET,使得开发者可以快速、便捷地创建动态网站、Web...

    ASP.NET就业实例教程-辅助资料.rar

    6. **状态管理**:了解ASP.NET中如何保持用户状态,如ViewState、Session、Cookie和Querystring等。 7. **AJAX与jQuery**:学习如何在ASP.NET中集成AJAX技术,提高用户体验,同时掌握JavaScript库jQuery的使用,...

Global site tag (gtag.js) - Google Analytics