Ideas for how to deal with viewstate when using ASP.NET AJAX and update panels

末鹿安然 提交于 2020-02-04 14:33:09

问题


Here is a class that I wrote to solve some issues that I was having with viewstate. It stores the info in the users session and increments a value to track which state to show. The difficulty is that there is no support for the back button. The reason I originally had this was that before AJAX came along the viewstate was being send down to the client instead of being stored on the server. I figured that by storing it on the server i could make the client experience much richer. Now with distributed caching through projects like velocity this could be stored in a cache.

I'd love to hear some comments and any tips that people might have.

Public Class ViewState
    ''' <summary>
    ''' Saves the state to the users session
    ''' </summary>
    ''' <param name="viewState">The viewstate object to serialize</param>
    ''' <param name="NoSerialize"></param>
    ''' <returns>Returns the KEY of the string that was saved.</returns>
    ''' <remarks></remarks>
    Function SaveState(ByVal viewState As Object, Optional ByVal NoSerialize As Boolean = False)
        HttpContext.Current.Session("VSID") = HttpContext.Current.Session("VSID") + 1
        If NoSerialize Then
            HttpContext.Current.Session(CacheString) = viewState
        Else
            Dim Format As New LosFormatter
            Dim Writer As New System.IO.StringWriter
            Format.Serialize(Writer, viewState)
            HttpContext.Current.Session(CacheString) = Writer.ToString
        End If
        Return HttpContext.Current.Session("VSID")
    End Function
    ''' <summary>
    ''' Returns a deserialized copy of the viewstate object
    ''' </summary>
    ''' <param name="SQLSTATE"></param>
    ''' <param name="NoSerialize"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function LoadState(ByVal SQLSTATE, Optional ByVal NoSerialize = False) As Object
        If NoSerialize Then
            If Not HttpContext.Current.Session(CacheString(SQLSTATE)) Is Nothing Then
                Return HttpContext.Current.Session(CacheString(SQLSTATE))
            Else
                HttpContext.Current.Trace.Warn("No ViewState Object Found")
            End If
        Else
            Dim Format As New LosFormatter
            If Not HttpContext.Current.Session(CacheString(SQLSTATE)) Is Nothing Then
                Return Format.Deserialize(HttpContext.Current.Session(CacheString(SQLSTATE)))
            Else
                HttpContext.Current.Trace.Warn("No ViewState Object Found")
            End If
        End If
    End Function
    ''' <summary>
    ''' AJAX Viewstate
    ''' Saves the state to the users session
    ''' </summary>
    ''' <param name="viewState">The viewstate object to serialize</param>
    ''' <param name="VSID">The ID that the page uses to find the viewstate item</param>
    ''' <param name="NoSerialize"></param>
    ''' <returns>Returns the KEY of the string that was saved.</returns>
    ''' <remarks></remarks>
    Function SaveState(ByVal viewState As Object, ByVal VSID As String, Optional ByVal NoSerialize As Boolean = False)
        HttpContext.Current.Session("VSID") = HttpContext.Current.Session("VSID") + 1
        If NoSerialize Then
            If VSID = "" Then
                HttpContext.Current.Session(CacheString) = viewState
                Return HttpContext.Current.Session("VSID")
            Else
                HttpContext.Current.Session("VSID") = HttpContext.Current.Session("VSID") + 1
                HttpContext.Current.Session(CacheString) = viewState
                HttpContext.Current.Session(CacheString(VSID)) = viewState
                Return HttpContext.Current.Session("VSID")
            End If
        Else
            Dim Format As New LosFormatter
            Dim Writer As New System.IO.StringWriter
            Format.Serialize(Writer, viewState)
            If VSID = "" Then
                HttpContext.Current.Session("VSID") = HttpContext.Current.Session("VSID") + 1
                HttpContext.Current.Session(CacheString) = Writer.ToString
                Return HttpContext.Current.Session("VSID")
            Else
                HttpContext.Current.Session("VSID") = HttpContext.Current.Session("VSID") + 1
                HttpContext.Current.Session(CacheString) = Writer.ToString
                HttpContext.Current.Session(CacheString(VSID)) = Writer.ToString
                Return HttpContext.Current.Session("VSID")
            End If
        End If
    End Function
    ''' <summary>
    ''' Gets the string representing the cached viewstate object.
    ''' </summary>
    ''' <param name="VSID">Use this to override the session VSID property and use your own.</param>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property CacheString(Optional ByVal VSID As Integer = 0) As String
        Get
            If VSID = 0 Then
                Return "ViewState" & HttpContext.Current.Session("VSID")
            Else
                Return "ViewState" & VSID
            End If
        End Get
    End Property
End Class

The following code goes in the code behind for your asp.net page:

Protected Overrides Sub SavePageStateToPersistenceMedium(ByVal viewState As Object)
        Dim VState As New ViewState
        If String.IsNullOrEmpty(Request.Form("__SQLVIEWSTATE")) = False Then
            RegisterHiddenField("__SQLVIEWSTATE", VState.SaveState(viewState, Request.Form("__SQLVIEWSTATE")))
        Else
            RegisterHiddenField("__SQLVIEWSTATE", VState.SaveState(viewState))
        End If
    End Sub
    Protected Overrides Function LoadPageStateFromPersistenceMedium() As Object
        Dim VState As New ViewState
        Return VState.LoadState(Request.Form("__SQLVIEWSTATE"))
    End Function

回答1:


Before you roll your own code to persist the viewstate to the session, have you tried the built in functionality?

protected override PageStatePersister PageStatePersister
{
    get
    {
        return new SessionPageStatePersister(this);
    }
}

(C# version shown). Maybe this will solve your back button issue?

Edit to answer comment: I think this is the VB equivalent:

Public Overrides Function GetStatePersister() As PageStatePersister
  Return New SessionPageStatePersister(Page)
End Function 'GetStatePersister

I don't know how this handles the back-button, but I believe that it stores up to 10 states per page.



来源:https://stackoverflow.com/questions/271269/ideas-for-how-to-deal-with-viewstate-when-using-asp-net-ajax-and-update-panels

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!