5

我有一个自定义的用户控件,我正在使用它的主机动态创建控件,我遇到了一个奇怪的情况,我似乎丢失了 ViewState 信息。在 base.SaveViewState() 调用上重写的 SaveViewState 方法中,我希望它返回一个包含 ViewState 中所有内容的对象,但它返回的是 null。

protected override object SaveViewState()
{

    object[] tempState = new object[2];
    tempState[0] = base.SaveViewState(); //***suspected issue here, tempState[0] == null -- why?
    //? this.ViewState["CompanyID"] returns me the guid I'm expecting
    //... code instantiating and populating lstDataControlInfos
    tempState[1] = lstDataControlInfos;
    return tempState;
}

我在该方法中设置了一个断点,我可以使用即时窗口查询 ViewState["CompanyID"] 并验证 ViewState 中确实存储了一个 CompanyID。也许我对 ViewState 有误解,但该调用不应该返回 ViewState 中已经存在的内容(包括我的 CompanyID)吗?这个问题在被覆盖的 LoadViewState 方法中成为回发问题,因为我不再有任何方法可以从 ViewState 中获取 CompanyID;它返回为空。

protected override void LoadViewState(object savedState)
{
    object[] tempState = (object[])savedState;
    //tempState[0] == null, as it was stored in the previous SaveViewState call
    //any reference to ViewState["CompanyID"] comes back null
    base.LoadViewState(tempState[0]);
}

我提到我有动态控件,我在这个控件中序列化和反序列化 ViewState,这些似乎都工作正常。当我知道一个事实并且可以验证(通过即时窗口)在 SaveViewState 调用期间 ViewState 中有数据时,什么会导致 base.SaveViewState() 返回 null?

4

1 回答 1

3

将值保存到 ViewState 时,如果正在跟踪 ViewState,则该值被标记为脏。

跟踪从 TrackViewState 开始,它在 Initialize 之后和 Load 之前。

跟踪在 PreRender 之后的 SaveViewState 中结束。

如果在 ViewState 中设置值时未跟踪 ViewState,则在调用 SaveViewState 时不会保留它。这是一件好事:这意味着您可以在 Init 阶段使用 ViewState 而不会使序列化的 ViewState 膨胀。

当您将控件动态添加到树中时,您应该注意:

  • 在将控件添加到控件树之前设置的值不会保留,即使在跟踪 ViewState 时添加控件也是如此。

  • 如果您处于跟踪 ViewState 的阶段,则在将控件添加到控件树设置的值将保持不变。

您在页面生命周期的哪个时间点设置 ViewState["CompanyID"],您是在将控件添加到控件树之前还是之后这样做?

于 2012-10-23T20:31:05.430 回答