用户名: 密码: 免费注册 忘记密码? 加入收藏 | 设为首页
ASP.NET 2.0的视图状态持久性机制
学院首页 | 资讯中心 | 服务器软件 | 系统工具 | 系统软件 | 办公软件 | 聊天软件 | 多 媒 体 | 网页制作 | 网站运营 | 平面设计
艺术欣赏 | 数据库软件 | 程序开发 | 网络组建 | 源码下载 | 驱动下载 | 软件下载 | 电脑安全 | IT创业 | IT博客 | IT社区
硬件数码导航 | 硬件频道 | 本本频道 | MP3频道 | 相机频道 | 手机频道 | 显卡频道 | LCD 频道 | 音箱音频 | 行情 | 评测 | 导购
学院专题 软件 - 系统 - 办公 - 聊天 - 多媒体 - 网页制作 - IT创业 - 运营 - 平面 - 设计欣赏 - 数据库 - 程序 - 服务器 - 组网

 当前位置: 首页>>技术频道>>程序>>ASP.net教程>>正文

ASP.NET 2.0的视图状态持久性机制

日期:2006-9-15 4:27:26     来源:博客园   编辑:   

    前言

  只要对ViewState稍有了解,就会知道,Asp.net页面中ViewState一般是存储在页面的一个隐藏域中:

  <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="一堆乱七八糟的东西">

  当我们浏览页面源文件时,看到的那一大堆(特别是当页面有个有大量数据的DataGrid,或在ASP.NET2.0中的GridView时)乱七八糟的东西的时候,那就是ViewState了 。

  基础知识

  因为,在ASP.NET2.0中ViewState的持久性存储机制有了些新的变化,所以,还是简单介绍下相关的东西 。

  在ASP.NET1.1中,只提供了页面隐藏域的持久性机制,这样在某些情况下不得不放弃使用ViewState,试想下,如果你的DataGrid中有上万条记录(别认为这种变态的需要是没有的,有人就碰到过),如果启用了ViewState,你感保证你的IIS服务器能承受得住吗,网络承受得主吗?当然你是可以通过重写Page.SavePageStateToPersistenceMedium()方法来更改你的存储机制,但别忘了重写Page.LoadPageStateFromPersistenceMedium(),它们可是一对的啊 。

  ASP.NET2.0 中的默认视图状态持久性机制依然是在页上的一个隐藏 HTML 元素(一个 type 属性设置为 "hidden" 的元素)中将状态信息保留为一个 Base64 编码的字符串 。 ASP.NET 页使用 HiddenFieldPageStatePersister 对象执行此项工作,并使用一个 IStateFormatter 实例对对象状态信息进行序列化和反序列化 。 或者,对于带宽和资源有限的移动客户端,您也可以使用 SessionPageStatePersister 类在服务器上的 Session 对象中存储页的视图状态,其实也就多了个Session持久机制而已,让我们把页面状态保存在Session中,而不是页面中,这对带宽是一种节省 。

  但你要深入的了解ViewState持久机制的话,抽象类PageStatePersister你是应该去了解的,要在不能支持现有视图状态持久性机制的客户端上保留视图状态,可以扩展 PageStatePersister 类,引入您自己的视图状态持久性方法,并且可以使用页适配器将 ASP.NET 应用程序配置为根据为其提供页的客户端的类型使用不同的视图状态持久性机制 。 从 PageStatePersister 类派生的类必须重写 Save 抽象方法,以便在持久性介质中存储视图状态和控件状态,同时重写 Load 方法以提取状态信息 。 如果需要将视图状态和控件状态序列化为字符串,可以使用通过 StateFormatter 属性来访问的 IStateFormatter 对象 。 它可以高效地将对象状态信息序列化和反序列化为 Base64 编码字符串 。 还可以重写 StateFormatter 属性以提供自己的对象状态序列化机制,如何为之,我的代码中都有介绍,很简单,看看就明白了 。

  ViewState持久性机制

  隐藏域

  这个就不介绍了,默认的就是这种 。 就入前言中的那样 。

  Session

  在ASP.NET2.0中只要重写PageStatePersister属性就可以了 。

protected override PageStatePersister PageStatePersister
{
 get
 {
  return new SessionPageStatePersister(Page);
 }
}

  要是在ASP.NET1.1中需要重写LoadPageStateFromPersistenceMedium这两个方法:

protected override object LoadPageStateFromPersistenceMedium()
{
 return Session["ViewState"];
}

protected override void SavePageStateToPersistenceMedium(object viewState)
{
 Session["ViewState"] = viewState;
 RegisterHiddenField("__VIEWSTATE", "");
}

  数据库(我的示例是SQL Server2000)

  在ASP1.1中,请注意下面紫色的那行,我也不太清楚那有什么用,它让我郁闷了好几天,等下你就明白我的郁闷了 。 还有下面的代码只是凑我的源码中拷贝出来的,你完全可以不这样写的,除了那些必要的外 。

protected override void SavePageStateToPersistenceMedium(object state)
{
 string viewStateID = "VIEWSTATE#" + Session.SessionID.ToString() + "#" + DateTime.Now.Ticks.ToString();
 ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateID);
 ClientScript.RegisterHiddenField("__VIEWSTATE","");//请注意

 try
 {
  if (losFormatter == null)
  {
   losFormatter = new LosFormatter();
  }
  StringWriter sw = new StringWriter();
  losFormatter.Serialize(sw, state);
  Common.ViewStateData vsd = new ViewStateData();
  vsd.ViewStateID = viewStateID;
  vsd.ViewState = sw.ToString();
  da = new DataAccess();
  string error = da.SaveViewState(vsd);
  Response.Write(error);
 }
 catch (Exception ex)
 {
  Response.Write(ex.Message);
 }
}

protected override object LoadPageStateFromPersistenceMedium()
{
 string viewState = string.Empty;
 try
 {
  if (losFormatter == null)
  {
   losFormatter = new LosFormatter();
  }
  string stateID = Page.Request["__VIEWSTATE_KEY"].ToString();
  da = new DataAccess();
  viewState = da.LoadViewState(stateID);
 }
 catch
 {}

 return losFormatter.Deserialize(viewState);
}

  在ASP2.0中这行代码基本是可以的,为什么是基本呢,因为就是上面那行 ClientScript.RegisterHiddenField("__VIEWSTATE","");

  有没有这行,在Asp.net1.1中都是可行的,我也是参考过别人的代码,这行就这么加入了,加了这行后,只是在页面中多了个

<input type="hidden" name="__VIEWSTATE" value="" />
  也就是运行后页面的源文件中有两个这样的东西 。 去掉那行也可以,所以我不明白语句是用做什么的,请明白的告诉我吧 。 但是在Asp.net2.0中就不行,有如下错误:

The state information is invalid for this page and might be corrupted.

  反正当时就是晕晕的,我以前从来没有碰到过如是错误,去google也无所得,是啊,打死我也不知道是那句错了啊,就这么郁闷了两天,问题无法解决,本人天生愚钝的,我跟踪视图状态的存入数据库与从数据库的读取的整个过程,硬是找不到错误,我就反复思考这些代码,惟有那行,我就是有点迷惑,为什么还要页面注册一个“__VIEWSTATE”的隐藏域呢,于是我就注释掉这行,居然可以运行了,所以我还是不明白那行是什么用意 。

  当然我们还可以通过写一个PageStatePersister新子类也可以完成上述功能,这是ASP.NET2.0新增的:

namespace PageAdapter
{
using System;
using System.IO;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;

[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]

public class DatabasePageStatePersister : PageStatePersister
{
 public DatabasePageStatePersister(Page page): base(page)
 {}
 //
 // Load ViewState and ControlState.
 //
 public override void Load()
 {
  string viewState;
  IStateFormatter formatter = this.StateFormatter;
  DataAccess da = new DataAccess();
  string stateID = base.Page.Request["__VIEWSTATE_KEY"].ToString();
  viewState = da.LoadViewState(stateID);
  Pair statePair = (Pair)formatter.Deserialize(viewState);
  ViewState = statePair.First;
  ControlState = statePair.Second;
 }
 //
 // Persist any ViewState and ControlState.
 //
 public override void Save()
 {
  if (ViewState != null || ControlState != null)
  {
   if (Page.Session != null)
   {
    string viewStateID = "VIEWSTATE#" + base.Page.Session.SessionID.ToString() + "#" + DateTime.Now.Ticks.ToString();
    base.Page.ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateID);
    Pair statePair = new Pair(ViewState, ControlState);
    IStateFormatter formatter = this.StateFormatter;
    // Serialize the statePair object to a string.

    string serializedState = formatter.Serialize(statePair);
    ViewStateData vsd = new ViewStateData();
    vsd.ViewStateID = viewStateID;
    vsd.ViewState = serializedState;
    DataAccess da = new DataAccess();
    string error = da.SaveViewState(vsd);
   }
   else
    throw new InvalidOperationException("Session needed for StreamPageStatePersister.");
  }
 }
}

}

  再有重写PageStatePersister属性就可以了:

protected override PageStatePersister PageStatePersister
{
 get
 {
  return new DatabasePageStatePersister(Page);
 }

gigi_miao
  ▼ 下一篇新闻 使ASP.NET中的数据库操作变得简单
  ▲ 上一篇新闻 ASP.NET服务器控件之视图状态        网友发表观点请进入=>



我要纠错】【进入论坛交流】【关闭此页

文章搜索
   
最新文章

 
·千名爱好者参与首届PHP调查
·腾讯称QQ通讯信息密钥加密 不会被
·雅虎反超Google排名搜索第二
·中搜等十余家IT企业因流氓软件被
·盛大前员工克隆网游装备获暴利被
·凤凰网将向迅雷提供娱乐及宽带内
·信产部出手规范 新浪式企业法律架
·雅虎中国称旗下软件早已没有流氓
·中搜停止划词搜索与流氓软件决裂

广告赞助
相关文章 相关教程下载
焦点信息
·腾讯称QQ通讯信息密钥加密 不会被监听
·信产部出手规范 新浪式企业法律架构不得不改
·盛大前员工克隆网游装备获暴利被追刑责
·凤凰网将向迅雷提供娱乐及宽带内容
·雅虎中国称旗下软件早已没有流氓问题
·雅虎反超Google排名搜索第二
网友评论:(评论内容只代表网友观点,与本站立场无关!)
发表评论     Hard168社区推荐帖子
姓 名: *
* 请网友遵纪守法并注意语言文明。
IT人物推荐

王江民
马云
柳传志



关于本站    联络方式    广告服务    意见信箱    加入收藏   设为首页    -
本站部分内容来自网上,如有侵权部分,敬请告知,我们会在24小时内给予处理
版权所有:Hard168.Com,如需转载文章请与我们取得联系
京ICP备05063857号 Designed by Hard168.Com
ASP.NET 2.0的视图状态持久性机制