【问题标题】:Viewstate does not persist after postback回发后视图状态不保留
【发布时间】:2012-03-21 10:05:14
【问题描述】:

我在为控件 (vb.net) 保留回发视图状态时遇到一些问题

这是我控制的一些代码:

Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
            MyBase.OnInit(e)
            Me.EnableViewState = True
            Me.ViewStateMode = System.Web.UI.ViewStateMode.Enabled
            If Not Page.IsPostBack Then
                _SortTime = DateTime.Now
                _SortTime.AddSeconds(-10) ' incase the fileserver and webserver date are out of sync
                ViewState("PageLoadTimeStamp") = _SortTime      
            End If
        End Sub

加载:

Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
        MyBase.OnLoad(e)

        _SortTime = CType(ViewState("PageLoadTimeStamp"), DateTime)

End Sub

但是在每次回发时,视图状态又是空的。

更新:我想做什么? 我想存储用户首次加载页面的时间。然后,用户将进行多次回发。在每次回发时,我都需要知道那个时间。

更新 2: 背景:

  • aspx 页面 (Editor.aspx) 将动态加载 Web 控件 (ObjectsEditor.ascx)
  • ObjectsEditor.ascx 包含单个自定义控件 (Objects.vb)
  • Objects.vb 将创建另一个自定义控件 (ObjectsContainer.vb) 并将其添加到它的控件中 需要持久化视图状态的是 ObjectsContainer。

我在任何地方都设置了 EnableViewState = "true",但仍然没有结果。我真的需要在这里设置这些属性吗? (ViewStateMode 和 EnableViewState)如果没有,我应该在哪里处理,这些属性之间有什么区别?

非常感谢。

【问题讨论】:

    标签: .net vb.net viewstate page-lifecycle


    【解决方案1】:

    我在这里看到了一些正确的答案,但我没有看到任何详细的解释,所以我想我会插话:

    ASP.NET 有一个相当复杂的请求/响应生命周期。每个循环都会运行一组事件,例如InitLoad 等。根据this article,特别是this image,有一个名为TrackViewState() 的方法在Init 事件之后执行,但是在InitComplete 事件之前。这意味着,如果像 OP 所做的那样在 Init 事件中进行了对 ViewState 的任何更改,则它们将不会被持久化(跟踪)。

    还有一个名为LoadViewState() 的附加方法,它获取通过__VIEWSTATE 表单值发布的ViewState 数据并将其加载到当前ViewState 集合中。这在InitComplete 事件之后但PreLoad 事件之前执行。这意味着在执行LoadViewState() 之前已经设置为ViewState 的值可能会被覆盖。

    现在,知道这两个事件何时发生,并知道在它们之前和之后执行的ViewState 持久性方法,我们可以推断出可以安全设置ViewState 值的最早事件是PreLoad 事件.在此事件之前设置的值可能会被覆盖,因此不会持久化。

    因此,要回答您的问题,请在 OnPreLoad() 方法中设置您的 ViewState 值,或者按照其他人的建议并在 OnLoad() 方法中执行此操作,您的值应该保持不变。

    【讨论】:

      【解决方案2】:

      直到Load-event 才会加载页面的ViewState。所以你可以存储你的值,但不能在OnInit中重新加载它。

      http://msdn.microsoft.com/en-us/library/ms972976.aspx

      编辑:老实说,我还不确定是什么导致了您的问题(也没有时间进一步调查),但尝试这种方式可以按预期工作:

      Private Property SortTime As Date
          Get
              If ViewState("PageLoadTimeStamp") Is Nothing Then
                  ViewState("PageLoadTimeStamp") = DateTime.Now.AddSeconds(-10)
              End If
              Return DirectCast(ViewState("PageLoadTimeStamp"), Date)
          End Get
          Set(value As Date)
              ViewState("PageLoadTimeStamp") = value
          End Set
      End Property
      
      Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
          MyBase.OnInit(e)
          'Me.EnableViewState = True
          'Me.ViewStateMode = System.Web.UI.ViewStateMode.Enabled
          'If Not Page.IsPostBack Then
          '    _SortTime = DateTime.Now
          '    _SortTime.AddSeconds(-10) ' incase the fileserver and webserver date are out of sync
          '    ViewState("PageLoadTimeStamp") = _SortTime
          'End If
      End Sub
      
      Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
          MyBase.OnLoad(e)
          Dim time = SortTime
          '_SortTime = CType(ViewState("PageLoadTimeStamp"), DateTime)
      End Sub
      

      【讨论】:

      • 好的。我将加载视图状态部分移至 onload。我会在一分钟内告诉你。
      • 它不适用于将加载视图状态移动到 onload 方法。您还有其他想法可以帮助我吗?
      • @ThomasDekiere:编辑了我的答案以提供另一种具有属性的工作方法。我已经注释掉了你现在多余的代码(希望如此)。注意Dim time = SortTime这行只是为了演示,其实也是多余的。
      • @ThomasDekiere:到现在它还在工作,但现在不行了?它对我有用,只生成一次,并且在以下回发中始终相同。我已经用一个简单的 UserControl 对其进行了测试。也许您需要提供更多详细信息。这是什么类型的控件,您如何重新加载页面,是否动态创建了任何内容,以及该控件嵌套在哪里?您可以尝试覆盖control.LoadViewState(第一次调用base.LoadViewState)来阅读它。
      • 例如,如果它嵌套在一个数据绑定控件(如 GridView)中,您在回发时进行数据绑定,则 ViewState 将丢失。另请注意,EnableViewState 将从父控件继承到子控件(例如,您设置了 GridView EnableViewState=false 并在其 TemplateFields 中声明了此控件,那么即使您设置了EnableViewState=true,您的控件也会继承此设置) .
      【解决方案3】:

      当回发发生时(即当表单提交到服务器时),在代码隐藏页面中设置的变量值将从客户端系统的内存中删除

      http://social.msdn.microsoft.com/Forums/en-US/netfx64bit/thread/961985e8-37fe-4b0d-8eb9-9920e4b298d7/

      【讨论】:

      • 阅读那篇文章的第二段。这就是我在这里想要做的。但它不起作用。
      【解决方案4】:
      Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
          Me.EnableViewState = True
          Me.ViewStateMode = System.Web.UI.ViewStateMode.Enabled             
          If Not Page.IsPostBack Then
              _SortTime = DateTime.Now                 
              _SortTime.AddSeconds(-10) ' incase the fileserver and webserver date are out of sync                 
               ViewState("PageLoadTimeStamp") = _SortTime                   
          End If 
      End Sub 
      

      编写这段代码

      【讨论】:

      • 这是可选的,取决于你的逻辑
      • 我已经完成了这项工作,并将加载视图状态移动到控件的加载部分。但还是一样的结果。回发后 Viewstate 什么都不是。
      【解决方案5】:

      我找不到回发后视图状态没有持续存在的原因,但我找到了另一种使用 controlstate 来保存值的方法。这是我的实现:

       Public Property SortTime() As DateTime
              Get
                  Return _SortTime
              End Get
              Set(ByVal value As DateTime)
                  _SortTime = value
              End Set
          End Property
      

      添加以下重写方法:

          Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
              Page.RegisterRequiresControlState(Me)
              MyBase.OnInit(e)
          End Sub
      
          Protected Overrides Function SaveControlState() As Object
              Return _SortTime
          End Function
      
          Protected Overrides Sub LoadControlState(ByVal savedState As Object)
              Dim state As DateTime = CType(savedState, DateTime)
              Me._SortTime = state
          End Sub
      

      给 OnLoad 中的属性赋值

          Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
              If Not Page.IsPostBack Then
                  SortTime = DateTime.Now
              End If
          End Sub
      

      现在我可以在页面加载后调用该属性,并且它将始终具有在第一个页面加载时设置的值。它不会在回发时改变,也不会在回发时消失。

      我确信视图状态也可以做到这一点,但由于某种原因,这对我不起作用。

      感谢您帮助我了解 Viewstate,我相信我迟早要使用 ViewState。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-19
        相关资源
        最近更新 更多