使用ASP.NET viewstate,在生命周期中访问视图状态是否有最佳实践?

时间:2010-11-08 15:54:34

标签: asp.net viewstate

在构建自定义控件时,我看到了两种使用viewstate的模式。一种是使用属性将视图状态访问伪装成持久数据。

   public bool AllowStuff
   {
       get
       {
           return (ViewState[constKeyAllowStuff] != null) ?
               (bool)ViewState[constKeyAllowStuff] : false;
       }
       set { ViewState[constKeyAllowStuff] = value; }
   }

另一种方法是使用私有成员字段并覆盖控件上的Load / SaveViewState方法并明确处理它们:

 protected override object SaveViewState()
 {
     object[] myViewState = new object[2];
     myViewState[0] = base.SaveViewState();
     myViewState[1] = _allowStuff;
     return myViewState;
 }

 protected override void LoadViewState(object savedState)
 {
     object[] stateArray = (object[])savedState;
     base.LoadViewState(stateArray[0]);
     _allowStuff = (bool)stateArray[1];
 }

(为了清晰起见,我进行了大量的安全检查,所以请忽略它。)

一种方法比另一种方法有特别的优势吗?我看不出他们的表现如何明显不同。版本1是懒惰的,所以如果你在通过期间不需要那个特定值,我想你会节省一点。版本1也更抽象,更好地隐藏细节。版本2更清楚地表明数据何时实际有效并且可以读取或修改(在加载和保存之间),因为它更清楚地在ASP.NET生命周期内工作。

版本2确实需要更多的样板代码(属性,支持私有字段和两个地方的视图状态处理),而不是版本1,它将所有这些组合到一个地方。

那么想法?

2 个答案:

答案 0 :(得分:2)

私有成员字段方法通常用于不能直接访问ViewState状态包的对象。所以从某种意义上说,我会将选项一用于自定义控件,用户控件或页面,或任何具有ViewState或类似属性的选项,但对于不能直接访问ViewState的对象使用另一个选项(如您希望能够“序列化”并存储在视图状态中的类。例如,自定义控件将使用该方法为不直接引用viewstate的子对象存储状态。

HTH。

答案 1 :(得分:1)

我将使用ControlState而不是viewstate的所有拳头,以便在视图状态关闭的容器中正常工作。

然后我会覆盖init,savecontrolstate,loadcontrolstate和databind。

并确保注册控件使用控件状态,即Page.RegisterRequiresControlState(this)

哦,优点是你的控件更强大(用户不能轻易搞砸),并且在动态加载和回发“更好”时可以正常工作