`
cloudtech
  • 浏览: 4612765 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

在禁用视图状态的情况下仍然使用ViewState对象

 
阅读更多

在禁用视图状态的情况下仍然使用ViewState对象

本文节选自《庖丁解牛:纵向切入ASP.NET 3.5控件和组件开发技术》一书


当开发人员禁用了页面或控件视图状态时。控件开发人员一般在无奈情况下会使用控件状态,要重写LoadControlState,SaveControlState,还有一个OnInit方法,这样固然完全可以实现控件重要数据的控件状态数据保存。但一般LoadControlState和SaveControlState方法都要开发人员自定义编程,比较麻烦,更适合对控件中复杂的自定义类型数据进行对象序列化操作,比如一些简单的类型如:string,int,bool,color,datetime,byte,arraylist等如果是控件重要属性的话,也都挤到LoadControlState 和 SaveControlState方法中,则会显得比较啰唆。
想一下,如果页面视图没有禁用时该多好,可以以this.ViewState["Text"]的格式直接使用Control中的ViewState对象,非常方便。既然ViewState对象不管禁用还是不禁用都在Control类中是存在的,那不用它岂不浪费。这一节主要内容就是如何实现在禁用视图状态下仍然可以使用ViewState对象。
该功能在主控件ControlStateControl中已经实现了。回顾一下主控件的代码片段:
/// <summary>
/// 获得本书更多内容,请看:
/// http://blog.csdn.net/ChengKing/archive/2008/08/18/2792440.aspx
/// </summary>
public class ControlStateControl : WebControl
{
//… …
[Description("使用ViewState属性来存储数据此属性")]
public string Text_ViewState
{
get
{
String s = (String)ViewState["Text_ViewState"];
return ((s == null) ? String.Empty : s);

}

set
{
ViewState["Text_ViewState"] = value;
}
}
//… …
protected override object SaveControlState()
{
Pair p = new Pair();
p.First = base.SaveViewState();
p.Second = ((IStateManager)FaceStyle).SaveViewState();
//… …
return p;
}

protected override void LoadControlState(object savedState)
{
if (savedState == null)
{
base.LoadViewState(null);
return;
}
else
{
//… …
base.LoadViewState(p.First);
//… …
}
}
//… …
}
在ControlStateControl中,属性Text_ViewState仍然存储在基类Control的ViewState对象中,且运行页面中同时禁用了页面和控件视图状态,但该属性仍然能够正确地应用视图状态。
在视图状态启用状态下,在LoadViewState方法中会默认调用基类的base.LoadViewState方法,其中就包含对基类中ViewState对象进行对象序列化的代码,如下:
protected virtual void LoadViewState(object savedState)
{
if (savedState != null)
{
this.ViewState.LoadViewState(savedState);
object obj2 = this.ViewState["Visible"];
if (obj2 != null)
{
if (!((bool)obj2))
{
this.flags.Set(0x10);
}
else
{
this.flags.Clear(0x10);
}
this.flags.Set(0x20);
}
}
}
其中这句this.ViewState.LoadViewState(savedState)为关键语句,还记得ViewState属性实际的类型为StateBag类,它是系统定义的类型视图状态实现类(我们在6.2.3小节探讨过)。
同样在,SaveViewState方法中也有序列化保存ViewState属性对象的代码,如下所示:
protected virtual object SaveViewState()
{
if (this.flags[0x20])
{
this.ViewState["Visible"] = !this.flags[0x10];
}
if (this._viewState != null)
{
return this._viewState.SaveViewState();
}
return null;
}
关键语句为this._viewState.SaveViewState(),ViewState是对外属性,其操作的变量就是StateBag类型的_viewState。
在视图状态被禁用的情况下,由于LoadViewState和SaveViewState不再被页框架调用(默认情况下是base.SaveViewState和base.LoadViewState方法不会再被调用),所以ViewState属性功能也就失效。
了解了ViewState对象的来龙去脉,现在就讲解一下在ControlStateControl控件中仍然可以使用ViewState的原因。在LoadControlState和SaveControlState方法中分别调用base.LoadViewState和base.SaveControlState,我们可以手动调用ViewState属性对象的对象正反序列化过程。归根到底,也就是说开发人员所谓的禁用视图实际上是禁止LoadViewState和SaveViewState两个方法的执行,但理论上我们只要启动控件状态,并把这两个方法的逻辑放到LoadControlState和SaveControlState中,仍然可以利用ViewState。
本节内容有些乖张,违反了ASP.NET设计页面状态的规则。既然ASP.NET框架把视图和控件状态已经分开了,建议在实际开发中分开处理,不要滥用。在LoadControlState方法中尽量只写控件状态相关逻辑,在LoadViewState中只写视图状态相关逻辑,毕竟ControlState是专门为存储控件必需的少量数据设计的。不过上面在ControlState中使用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 对动态...

    ASP.NET 控件的使用

    11.1.9 在GridView控件中使用ViewState 349 11.2 在GridView控件中使用字段 349 11.2.1 使用BoundField 350 11.2.2 使用CheckBoxField 352 11.2.3 使用CommandField 353 11.2.4 使用ButtonField 355 11.2.5 使用...

    ASP.NET.4揭秘

    11.1.9 在gridview控件中使用viewstate397 11.2 在gridview控件中使用字段398 11.2.1 使用boundfield398 11.2.2 使用checkboxfield401 11.2.3 使用commandfield402 11.2.4 使用buttonfield404 11.2.5 使用...

    ASP.NET2.0高级编程(第4版)1/6

    书中提供了大量的实例,可帮助读者快速掌握如何在.NET平台下开发功能强大的ASP.NET应用程序。本书适合有一些基础的ASP.NET初级程序员以及准备迁移到ASP.NET 2.0的编程老手。该书与《ASP.NET 2.0入门经典(第4版)》...

    2.ASP.NET.2.0.高级编程(第4版) [1/7]

    书中提供了大量的实例,可帮助读者快速掌握如何在.NET平台下开发功能强大的ASP.NET应用程序。本书适合有一些基础的ASP.NET初级程序员以及准备迁移到ASP.NET 2.0的编程老手。该书与《ASP.NET 2.0入门经典(第4版)》...

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

    因pdf的容量过大分4个压缩包打包,还有一个源码另外下载。 《.NET深入体验与实战精要》作者身为从事.NET一线开发的资深开发专家,常年耕耘...15.5.14 使用视图代替跨库操作 572 15.5.15 尽量避免大事务操作 572 15.5.16...

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

    因pdf的容量过大分4个压缩包打包,还有一个源码另外下载。 《.NET深入体验与实战精要》作者身为从事.NET一线开发的资深开发专家,常年耕耘...15.5.14 使用视图代替跨库操作 572 15.5.15 尽量避免大事务操作 572 15.5.16...

    ExtAspNet_v2.3.2_dll

    -为空则使用默认的提示信息,默认的提示信息支持多语言,建议一般情况下使用默认信息。 +为表单字段增加MarkInvalid和GetMarkInvalidReference函数(feedback:sun1299shine)。 -增加示例:form/form_validate....

    C#编程经验技巧宝典

    111 &lt;br&gt;0184 如何在ASP.NET中获取文件的扩展名 111 &lt;br&gt;0185 如何在ASP.NET中用URL在页面之间传值 112 &lt;br&gt;0186 如何使用IsPostBack实现ASP.NET页面加载 112 &lt;br&gt;0187 如何利用输出缓存技术缓存...

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

    -为空则使用默认的提示信息,默认的提示信息支持多语言,建议一般情况下使用默认信息。 +为表单字段增加MarkInvalid和GetMarkInvalidReference函数(feedback:sun1299shine)。 -增加示例:form/form_validate....

Global site tag (gtag.js) - Google Analytics