【问题标题】:ASP.NET WebForms Custom UserControl - base.SaveViewState() is returning null -- why?ASP.NET WebForms 自定义用户控件 - base.SaveViewState() 返回 null - 为什么?
【发布时间】:2012-10-23 20:22:44
【问题描述】:

我有一个自定义的用户控件,我正在使用它来动态创建控件,我遇到了一个奇怪的情况,我似乎丢失了 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;它返回 null。

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?

【问题讨论】:

    标签: c# asp.net user-controls webforms viewstate


    【解决方案1】:

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

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

    跟踪在 PreRender 之后的 SaveViewState 结束。

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

    当你向树中动态添加控件时,你应该注意:

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

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

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

    【讨论】:

    • 很复杂,呵呵。这一切都在 Telerik RadGrid 内完成。在 标记中,UserControlName 设置为我的 .ascx 控件。 _InsertCommand 和 _UpdateCommand 分别处理事件获取数据并通过设置属性将值传递给控件。在该属性的设置器中,我拉出 CompanyID (guid) 并通过另一个属性的 (CompanyID) 设置器将其推送到 ViewState。
    • 你是对的。它在控件上调用 TrackViewState 之前将数据推送到 UserControl,因此在 base.SaveViewState 调用中,它可能没有将 CompanyID 视为脏。虽然我可以在调用 TrackViewState 后尝试找到一种设置 CompanyID 的方法,但我可能只是增加 SaveViewState 中“tempState”的数组大小并添加 CompanyID。无论如何,谁需要 ViewState,对吧? ;) 谢谢!
    • 其实我在 ViewState 上发现了一个漂亮的方法,叫做 SetItemDirty。正是医生所要求的。
    • @Vitoc, "它在控件上调用 TrackViewState 之前将数据推送到 UserControl" - 如果这发生在事件处理程序中,一定是因为尚未添加控件到树呢。在这种情况下,在设置 CompanyID 之前将控件添加到树中可能会更简洁,而不是显式调用 ViewState.SetItemDirty。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-14
    • 2018-07-08
    • 1970-01-01
    • 2011-11-06
    • 1970-01-01
    • 1970-01-01
    • 2011-03-23
    相关资源
    最近更新 更多