linux社区爱心援助Linux认证系列教程业界动态站务新闻公司招聘网络学院网址大全LPI专题CISCO专题
设为首页
加入收藏
管理团队
JSP  
JAVA  
PERL  
 您的位置:首页 > 开发语言 > asp.net >
栏目导栏
  php
  JSP
  ASP
  asp.net
  JAVA
  c/c++/c#
  perl
  JavaScript
  Basic
  Delphi
资料搜索
热门文章
·NetBPM工作流的一个示例:请假
·Office Web Components(OWC)绘
·asp.net正则表达式语法
·asp.net 2.0 ajax中使用PopupC
·Ado.Net读取Excel常见问题总结
·数据源为空时如何让GridView显
·如何让UpdatePanel支持文件上传
·C#.Net的常见面试试题和参考答
·asp.net ajax客户端编程+jquer
·Brettle.Web.NeatUpload.dll支
·ASP.NET使用Cookie
·ASP.NET DEMO 15: 同时支持行单
·如何使IE的后退按钮无效
·如何在ASP.NET中用OWC绘制图表
·asp.net:正确判断当前用户角色
最新文章
·Ajax Control Toolkit Animati
·讨论一下类似BlogEngine内一次
·使用CSS+SiteMap+UserControl+
·Asp.net中多彩下拉框的实现
·浅谈ASP.NET的Postback
·分清ASP.NET AJAX中的Extender
·Tip:在使用AjaxControlTookit
·有关注册DataItem的一些可能被
·IIRF(Ionic's Isapi Rewrite
·asp.net 客户端回调功能的实现
·关于控件部分的看法--读Progra
·为什么在vista上做开发
·如何封装JS和CSS文件为服务器端
·岂今我看过的最强的排序算法
·设计模式学习笔记之单件模式
Google
 
ASP.NET2.0的控件状态和视图状态探讨
[ 作者:  加入时间:2007-11-26 16:21:22  来自:Linux联盟收集整理 ]
 基本概念 sGBLinux联盟
   sGBLinux联盟
    控件状态-为了让控件正常工作,有时需要存储控件状态数据。例如,如果编写了一个自定义控件,其中具有显示不同信息的不同选项卡,为使该控件如预期一样工作,控件需要知道在往返过程中选择的是哪个选项卡。ViewState 属性可用于此目的,但开发人员可能在页级别关闭了视图状态,从而有效地中断控件。为解决此问题,ASP.NET 页框架在 ASP.NET 2.0 版中公开了一种称为控件状态的新功能。 sGBLinux联盟
  ControlState 属性允许保持特定于控件的属性信息,不像 ViewState 属性一样可以关闭。若要使用控件状态,控件必须在初始化过程中调用 RegisterRequiresControlState 方法,然后重写 SaveControlState 和 LoadControlState 方法。 sGBLinux联盟
   sGBLinux联盟
    视图状态-视图状态是 ASP.NET 页框架默认情况下用于保存往返过程之间的页和控件值的方法。当呈现页的 HTML 形式时,需要在回发过程中保留的页的当前状态和值将被序列化为 Base64 编码的字符串,并输出到视图状态的隐藏字段中。通过实现自定义的 PageStatePersister 类以存储页数据,您可以更改默认行为并将视图状态存储到另一个位置(如 SQL Server 数据库)。有关将页状态存储到流上而不是隐藏的页字段中的示例,请参见 视图状态持久性机制的示例。 sGBLinux联盟
   sGBLinux联盟
    您可以通过使用页的 ViewState 属性将往返过程中的数据保存到 Web 服务器来利用自己的代码访问视图状态。ViewState 属性是一个包含密钥/值对(其中包含视图状态数据)的字典。 sGBLinux联盟
   sGBLinux联盟
    各自的优势与劣势 sGBLinux联盟
   sGBLinux联盟
    视图状态 sGBLinux联盟
   sGBLinux联盟
    使用视图状态的优点: sGBLinux联盟
   sGBLinux联盟
    ·不需要任何服务器资源 视图状态包含在页代码内的结构中。 sGBLinux联盟
   sGBLinux联盟
    ·实现简单 视图状态无需使用任何自定义编程。默认情况下对控件启用状态数据的维护。 sGBLinux联盟
   sGBLinux联盟
    ·增强的安全功能 视图状态中的值经过哈希计算和压缩,并且针对 Unicode 实现进行编码,其安全性要高于使用隐藏域。 sGBLinux联盟
   sGBLinux联盟
    使用视图状态的缺点 sGBLinux联盟
   sGBLinux联盟
    ·性能注意事项 由于视图状态存储在页本身,因此如果存储较大的值,用户显示页和发送页时的速度可能会减慢。尤其是对移动设备,其带宽通常是有限的。 sGBLinux联盟
   sGBLinux联盟
    ·设备限制 移动设备可能没有足够的内存容量来存储大量的视图状态数据。 sGBLinux联盟
   sGBLinux联盟
    ·潜在的安全风险 视图状态存储在页上的一个或多个隐藏域中。虽然视图状态以哈希格式存储数据,但它可以被篡改。如果直接查看页输出源,可以看到隐藏域中的信息,这导致潜在的安全性问题。 sGBLinux联盟
   sGBLinux联盟
    控件状态 sGBLinux联盟
   sGBLinux联盟
    使用控件状态的优点: sGBLinux联盟
   sGBLinux联盟
    ·不需要任何服务器资源 默认情况下,控件状态存储在页上的隐藏域中。 sGBLinux联盟
   sGBLinux联盟
    ·可靠性 因为控件状态不像视图状态那样可以关闭,控件状态是管理控件的状态的更可靠方法。 sGBLinux联盟
   sGBLinux联盟
    ·通用性 可以编写自定义适配器来控制如何存储控件状态数据和控件状态数据的存储位置。 sGBLinux联盟
   sGBLinux联盟
    使用控件状态的缺点: sGBLinux联盟
   sGBLinux联盟
    ·需要一些编程 虽然 ASP.NET 页框架为控件状态提供了基础,但是控件状态是一个自定义的状态保持机制。为了充分利用控件状态,您必须编写代码来保存和加载控件状态。 sGBLinux联盟
   sGBLinux联盟
  控件状态与视图状态示例 sGBLinux联盟
   sGBLinux联盟
    此示例演示如何创建一个名为 IndexButton 的自定义控件,该控件使用控件状态在多个页请求间维护关键状态信息。在 ASP.NET 2.0 版中引入的控件状态与视图状态类似,但功能上独立于视图状态。网页开发人员可能会出于性能原因而禁用整个页面或单个控件的视图状态,但他们不能禁用控件状态。控件状态是专为存储控件的重要数据(如一个页面控件的页数)而设计的,回发时必须用到这些数据才能使控件正常工作(即便禁用视图状态也不受影响)。默认情况下,ASP.NET 页框架将控件状态存储在页的一个隐藏元素中,视图状态也同样存储在此隐藏元素中。即使禁用视图状态,或是使用 Session 管理状态时,页面中的控件状态仍会传输至客户端,然后返回到服务器。在回发时,ASP.NET 会对隐藏元素的内容进行反序列化,并将控件状态加载到每个注册过控件状态的控件中。 sGBLinux联盟
   sGBLinux联盟
    此示例阐释了一个同时在控件状态和视图状态中保存状态的自定义控件。在此示例中,IndexButton 控件派生自 Button 类,还定义了一个 Index 属性,并将该属性保存在控件状态中。为了进行比较,IndexButton 还定义了一个 IndexInViewState 属性,该属性存储在 ViewState 字典中。为了了解控件状态和视图状态之间的差异,请使用本文附带的程序来演示 IndexButton 控件。 sGBLinux联盟
   sGBLinux联盟
    IndexButton控件源码 sGBLinux联盟
   sGBLinux联盟
   sGBLinux联盟
   sGBLinux联盟
  using System; sGBLinux联盟
  using System.ComponentModel; sGBLinux联盟
  using System.Security.Permissions; sGBLinux联盟
  using System.Web; sGBLinux联盟
  using System.Web.UI; sGBLinux联盟
  using System.Web.UI.WebControls; sGBLinux联盟
   sGBLinux联盟
  namespace CustomerControls sGBLinux联盟
  { sGBLinux联盟
   [ sGBLinux联盟
    AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal), sGBLinux联盟
    AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal), sGBLinux联盟
    ToolboxData("<{0}:IndexButton runat=\"server\"> </{0}:IndexButton>") sGBLinux联盟
   ] sGBLinux联盟
   sGBLinux联盟
   public class IndexButton : Button sGBLinux联盟
   { sGBLinux联盟
    private int indexValue; sGBLinux联盟
    [ sGBLinux联盟
     Bindable(true), sGBLinux联盟
     Category("Behavior"), sGBLinux联盟
     DefaultValue(0), sGBLinux联盟
     Description("The index stored in control state.") sGBLinux联盟
    ] sGBLinux联盟
   sGBLinux联盟
   public int Index sGBLinux联盟
   { sGBLinux联盟
    get sGBLinux联盟
    { sGBLinux联盟
     return indexValue; sGBLinux联盟
    } sGBLinux联盟
    set sGBLinux联盟
    { sGBLinux联盟
     indexValue = value; sGBLinux联盟
    } sGBLinux联盟
   } sGBLinux联盟
   sGBLinux联盟
   [ sGBLinux联盟
    Bindable(true), sGBLinux联盟
    Category("Behavior"), sGBLinux联盟
    DefaultValue(0), sGBLinux联盟
    Description("The index stored in view state.") sGBLinux联盟
   ] sGBLinux联盟
   sGBLinux联盟
   public int IndexInViewState sGBLinux联盟
   { sGBLinux联盟
    get sGBLinux联盟
    { sGBLinux联盟
     object obj = ViewState["IndexInViewState"]; sGBLinux联盟
     return (obj == null) ? 0 : (int)obj; sGBLinux联盟
    } sGBLinux联盟
    set sGBLinux联盟
    { sGBLinux联盟
     ViewState["IndexInViewState"] = value; sGBLinux联盟
    } sGBLinux联盟
   } sGBLinux联盟
   sGBLinux联盟
   protected override void OnInit(EventArgs e) sGBLinux联盟
   { sGBLinux联盟
    base.OnInit(e); sGBLinux联盟
    Page.RegisterRequiresControlState(this); sGBLinux联盟
   } sGBLinux联盟
   sGBLinux联盟
   protected override object SaveControlState() sGBLinux联盟
   { sGBLinux联盟
    //调用基类的方法,从基类得到控件状态的基值 sGBLinux联盟
    //如果indexValue不等于并且基类的控件状态不为null sGBLinux联盟
    //使用Pair作为便利的数据结构来高效保存(和在LoadControlState方法中还原) sGBLinux联盟
    //由两部分组成的控件状态 sGBLinux联盟
    object obj = base.SaveControlState(); sGBLinux联盟
    if (indexValue != 0) sGBLinux联盟
    { sGBLinux联盟
     if (obj != null) sGBLinux联盟
     { sGBLinux联盟
      return new Pair(obj, indexValue); sGBLinux联盟
     } sGBLinux联盟
     else sGBLinux联盟
     { sGBLinux联盟
      return (indexValue); sGBLinux联盟
     } sGBLinux联盟
    } sGBLinux联盟
    else sGBLinux联盟
    { sGBLinux联盟
     return obj; sGBLinux联盟
    } sGBLinux联盟
   } sGBLinux联盟
   sGBLinux联盟
   protected override void LoadControlState(object state) sGBLinux联盟
   { sGBLinux联盟
    if (state != null) sGBLinux联盟
    { sGBLinux联盟
     Pair p = state as Pair; sGBLinux联盟
     if (p != null) sGBLinux联盟
     { sGBLinux联盟
      base.LoadControlState(p.First); sGBLinux联盟
      indexValue = (int)p.Second; sGBLinux联盟
     } sGBLinux联盟
     else sGBLinux联盟
     { sGBLinux联盟
      if (state is int) sGBLinux联盟
      { sGBLinux联盟
       indexValue = (int)state; sGBLinux联盟
      } sGBLinux联盟
      else sGBLinux联盟
      { sGBLinux联盟
       base.LoadControlState(state); sGBLinux联盟
      } sGBLinux联盟
     } sGBLinux联盟
    } sGBLinux联盟
   } sGBLinux联盟
  } sGBLinux联盟
  }   代码讨论 sGBLinux联盟
   sGBLinux联盟
    IndexButton 控件的实现阐释了三个任务,必须执行这三个任务才能使控件参与控件状态: sGBLinux联盟
   sGBLinux联盟
    · 重写 OnInit 方法并调用 RegisterRequiresControlState 方法向页面注册,以参与控件状态。必须针对每个请求完成此任务。 sGBLinux联盟
   sGBLinux联盟
    · 重写 SaveControlState 方法,以在控件状态中保存数据。 sGBLinux联盟
   sGBLinux联盟
    · 重写 LoadControlState 方法,以从控件状态加载数据。此方法调用基类方法,并获取基类对控件状态的基值。如果 indexValue 字段不为零,而且基类的控件状态也不为空,Pair 类便可作为方便的数据结构使用,用来保存和还原由两部分组成的控件状态。 sGBLinux联盟
   sGBLinux联盟
  分析总结 sGBLinux联盟
   sGBLinux联盟
    从MSDN上的一系列的技术参考来看,ControlState应该是主要在自定义控件上使用,“ASP.NET 页框架提供了 ControlState 属性作为在服务器往返过程中存储自定义控件数据的方法”,这是MSDN上的原句,ASP.NET2.0只是为ControlState提供了一个基础,当 ControlState是一个自定义的状态保持机制,也就是说保持状态的机制需要你开发人员自己去完成,而不像ViewState,它有自己默认的状态保持机制。在自定义控件使用ControlState也许才是微软本意了,为的就避免在页面级别禁用掉ViewState后,自定义控件还能正常运行。当然这里的意思就是,某些控件的正确运行是依赖于它的状态信息的,在ASP.NET1.1中,如果禁用了ViewState,这样的控件就无法正确运行了。但引入了ControlState后就不同了,因为ControlState是禁用不掉的。 sGBLinux联盟
    sGBLinux联盟
    所以微软才提醒开发人员“请仅对那些在回发过程中对控件至关重要的少量关键数据使用控件状态,而不要将控件状态作为视图状态的备用选项使用”。明确说出,ControlState和 ViewState完全是两个东西,虽然它们可以完成相同的任务,新推出的ControlState既不是用来替代ViewState也不是用来做 ViewState的替补。它的使命是弥补ViewState的所不能完成的任务,让开发人员开发出更加健壮的控件。例如说,开发的自定义控件某个状态是至关重要的,缺少它就自定义控件不能正常工作,那么ControlState就该上场了。而且ControlState是自定义的状态保持机制,也限制了 ControlState自由的使用,你不但要在OnInit 方法并调用 RegisterRequiresControlState 方法向页面注册,而且要重写SaveAdapterControlState(),LoadAdapterControlState(object state)两个方法自己去实现要保存什么,怎样保存。根据我现在的理解,如果你需要保存该控件的10种不同状态,那你就得一一保存,再一一加载上去。从这点也就看出了微软的初衷了,那不是很明显吗,如果不需要ControlState那就不使用它吧,否则怎么它什么都让我们开发人员去做呢? sGBLinux联盟
   sGBLinux联盟
    这只是基础了,刚才我说了,似乎微软也是这么说的,ControlState针对的是自定义控件,其实我们真的要去开启基本控件例如Label 控件的ControlState,微软也是允许的,这就是稍深的内容了,这就涉及到控件适配器了(ControlAdapter)。如果需要了解这方面的内容,请看用控件适配器开启基本控件的ControlState。http://sifang2004.cnblogs.com/archive/2006/06/01/415288.html sGBLinux联盟
   sGBLinux联盟
    附录 sGBLinux联盟
   sGBLinux联盟
    为了更加充分理解上面的内容,需要对以下内容有个了解: sGBLinux联盟
   sGBLinux联盟
    Pair 类 sGBLinux联盟
   sGBLinux联盟
    用作存储两个相关对象的基本结构。它是在整个 ASP.NET 中(在如页面状态管理任务期间或配置节处理程序的过程中)有多种用法的实用工具类。可以在自己的代码中需要包含两个相关对象的结构的任意位置和不一定需要数据绑定的位置使用 Pair 类。Pair 类不将其对象引用 First 和 Second 封装在属性中;该类直接将它们作为公共类字段公开到所有调用代码。 sGBLinux联盟
   sGBLinux联盟
    Pair 类在页状态保留实现中有多种用法。最常见的用法是同时作为 ViewState 和 ControlState 集合的容器。在这种情况下,First 属性用于 ViewState,而 Second 用于 ControlState。 sGBLinux联盟
   sGBLinux联盟
    PageStatePersister 类 sGBLinux联盟
   sGBLinux联盟
    HTTP 请求和响应原本是无状态的。要在 HTTP 请求之间保持状态信息,ASP.NET 服务器页可以存储 Page 状态。此状态称为视图状态,它包含页和控件设置及数据,这些设置和数据使得页和控件看起来就像在上一次将它们提交到服务器然后又返回到客户端时,用户所看到并与之交互的页和控件一样。有几种机制可在对相同页的连续请求之间存储视图状态。PageStatePersister 抽象类表示这些状态信息存储机制的基类。 sGBLinux联盟
   sGBLinux联盟
    要在不能支持现有视图状态持久性机制的客户端上保留视图状态,可以扩展 PageStatePersister 类,引入您自己的视图状态持久性方法,并且可以使用页适配器将 ASP.NET 应用程序配置为根据为其提供页的客户端的类型使用不同的视图状态持久性机制。从 PageStatePersister 类派生的类必须重写 Save 抽象方法,以便在持久性介质中存储视图状态和控件状态,同时重写 Load 方法以提取状态信息。如果想知道如何写PageStatePersister的派生类,请参考视图状态持久性机制。 Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论
评论】【加入收藏夹】【 】【打印】【关闭
※ 相关链接
 ·asp.net2.0无刷新效果定时自动更新页面的例子  (2007-11-26 16:20:23)
 ·ASP.Net2.0使用Log4Net(二)  (2007-11-26 16:10:35)
 ·ASP.Net2.0使用Log4Net(一)  (2007-11-26 16:09:54)
 ·ASP.NET2.0 WebRource,开发微调按钮控件  (2007-11-02 13:54:47)
 ·asp.net2.0 动态生成静态页并分页实例  (2007-10-22 14:33:19)
 ·ASP.NET2.0MasterPage使用技巧总结  (2007-10-22 11:38:37)