My .Net application is recording some errors that I have tracked to the viewstate. I've read quite a bit on this, and found some information that simply hasn't helped me to get to the root of the problem. The errors are:
These errors happen somewhat infrequently, and often to the same small subset of users. Often, simply redirecting the user to the same page again does not result in the same error
In an attempt to resolve these errors, I implemented two different solutions. In each solution, I attempted a string replace for blank spaces as well as attempted to ensure that the viewstate string was an appropriate length by appending "=" characters. Additionally, in one test I compressed the viewstate as well. Code for each of those attempts is below.
Compressed Viewstate
Public Class baseCompressor
Inherits System.Web.UI.Page
Protected Overrides Function LoadPageStateFromPersistenceMedium() As Object
Dim viewState As String = Request.Form("__VSTATE")
viewState = viewState.Replace(" ", "+")
Dim mod4 As Integer = viewState.Length Mod 4
If mod4 > 0 Then
viewState += New String("=", 4 - mod4)
End If
Dim bytes As Byte() = Convert.FromBase64String(viewState)
bytes = compressor.Decompress(bytes)
Dim formatter As New LosFormatter()
Return formatter.Deserialize(Convert.ToBase64String(bytes))
End Function
Protected Overrides Sub SavePageStateToPersistenceMedium(viewState As Object)
Dim formatter As New LosFormatter()
Dim writer As New StringWriter()
formatter.Serialize(writer, viewState)
Dim viewStateString As String = writer.ToString()
Dim bytes As Byte() = Convert.FromBase64String(viewStateString)
bytes = compressor.Compress(bytes)
ScriptManager.RegisterHiddenField(Me, "__VSTATE", Convert.ToBase64String(bytes))
End Sub
End Class
Public NotInheritable Class compressor
Private Sub New()
End Sub
Public Shared Function Compress(data As Byte()) As Byte()
Using output As New MemoryStream()
Using gzip As New GZipStream(output, CompressionMode.Compress, True)
gzip.Write(data, 0, data.Length)
gzip.Close()
Return output.ToArray()
End Using
End Using
End Function
Public Shared Function Decompress(data As Byte()) As Byte()
Using input As New MemoryStream()
input.Write(data, 0, data.Length)
input.Position = 0
Using gzip As New GZipStream(input, CompressionMode.Decompress, True)
Dim output As New MemoryStream()
Dim buff As Byte() = New Byte(4096) {}
Dim read As Integer = -1
read = gzip.Read(buff, 0, buff.Length)
While read > 0
output.Write(buff, 0, read)
read = gzip.Read(buff, 0, buff.Length)
End While
gzip.Close()
Return output.ToArray()
End Using
End Using
End Function
End Class
Uncompressed Viewstate
Public Class baseNonCompressor
Inherits System.Web.UI.Page
Protected Overrides Sub SavePageStateToPersistenceMedium(viewState As Object)
Dim formatter As New LosFormatter()
Dim writer As New StringWriter()
formatter.Serialize(writer, viewState)
Dim viewStateString As String = writer.ToString()
Dim bytes As Byte() = Convert.FromBase64String(viewStateString)
ScriptManager.RegisterHiddenField(Me, "__VSTATE", Convert.ToBase64String(bytes))
End Sub
Protected Overrides Function LoadPageStateFromPersistenceMedium() As Object
Dim viewState As String = Request.Form("__VSTATE")
viewState = viewState.Replace(" ", "+")
Dim mod4 As Integer = viewState.Length Mod 4
If mod4 > 0 Then
viewState += New String("=", 4 - mod4)
End If
Dim bytes As Byte() = Convert.FromBase64String(viewState)
Dim formatter As New LosFormatter()
Return formatter.Deserialize(Convert.ToBase64String(bytes))
End Function
End Class
The results have still left me with the original two errors as well as a new error:
The new error occurs on the Deserialize call. Can anyone point me to what the problem might be? While my code is in VB, C# solutions are also welcomed.
First you should take the Base64
string and be sure it is valid. There are many online tools.
These might be wrong:
Dim mod4 As Integer = viewState.Length Mod 4
If mod4 > 0 Then
viewState += New String("=", 4 - mod4)
End If
From your code I sense you already know why. It's just wondering if it really behaves well in all cases, for example you shouldn't pad with four ====
if the modulo is 0.
Second, consider if this goes through a GET
. The HTTP protocol has hard limits on the status line's maximum length.
In other words: if you set it as a parameter in the URL's query string, and the data is big (next to 1K) I'd recommend strongly to prefer a POST
instead of a GET
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.