Unable to validate data.
or
Invalid length for a Base-64 char array.
or
Padding is invalid and cannot be removed.
Not fun for your users at all. Lets say you've taken the steps to turn off ViewState for any controls that don't need them. What else can you do? In my opinion, the easiest thing to do is to compress ViewState between postbacks on the page. But how is this done?
1. Create a new class called "Compressor" in your App_Code directory.
VB.NET:
Imports Microsoft.VisualBasic
Imports System.IO
Imports System.IO.Compression
Public Class Compressor
Public Shared Function Compress(ByVal data As Byte()) As Byte()
Dim output As New MemoryStream()
Dim gzip As New GZipStream(output, CompressionMode.Compress, True)
gzip.Write(data, 0, data.Length)
gzip.Close()
Return output.ToArray()
End Function
Public Shared Function Decompress(ByVal data As Byte()) As Byte()
Dim input As New MemoryStream()
input.Write(data, 0, data.Length)
input.Position = 0
Dim gzip As New GZipStream(input, CompressionMode.Decompress, True)
Dim output As New MemoryStream()
Dim buff As Byte() = New Byte(64) {}
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 Function
End Class
C#:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.IO.Compression;
/// <summary>
/// Summary description for Compressor
/// </summary>
public static class Compressor
{
public static byte[] Compress(byte[] data)
{
MemoryStream output = new MemoryStream();
GZipStream gzip = new GZipStream(output, CompressionMode.Compress, true);
gzip.Write(data, 0, data.Length);
gzip.Close();
return output.ToArray();
}
public static byte[] Decompress(byte[] data)
{
MemoryStream input = new MemoryStream();
input.Write(data, 0, data.Length);
input.Position = 0;
GZipStream gzip = new GZipStream(input, CompressionMode.Decompress, true);
MemoryStream output = new MemoryStream();
byte[] buff = new byte[64];
int read = -1;
read = gzip.Read(buff, 0, buff.Length);
while (read > 0)
{
output.Write(buff, 0, read);
read = gzip.Read(buff, 0, buff.Length);
}
gzip.Close();
return output.ToArray();
}
}
2. Throw the following methods in the code behind of the offending page(s).
VB.NET:
Protected Overloads Overrides Function LoadPageStateFromPersistenceMedium() As Object
Dim viewState As String = Request.Form("__VSTATE")
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 Overloads Overrides Sub SavePageStateToPersistenceMedium(ByVal 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)
ClientScript.RegisterHiddenField("__VSTATE", Convert.ToBase64String(bytes))
End Sub
C#:
protected override object LoadPageStateFromPersistenceMedium()
{
string viewState = Request.Form["__VSTATE"];
byte[] bytes = Convert.FromBase64String(viewState);
bytes = Compressor.Decompress(bytes);
LosFormatter formatter = new LosFormatter();
return formatter.Deserialize(Convert.ToBase64String(bytes));
}
protected override void SavePageStateToPersistenceMedium(object viewState)
{
LosFormatter formatter = new LosFormatter();
StringWriter writer = new StringWriter();
formatter.Serialize(writer, viewState);
string viewStateString = writer.ToString();
byte[] bytes = Convert.FromBase64String(viewStateString);
bytes = Compressor.Compress(bytes);
ClientScript.RegisterHiddenField("__VSTATE", Convert.ToBase64String(bytes));
}
3. Done
The net result of this is to compress your ViewState into a hidden field and decompress it when your page is initialized. Very little performance impact too. Pretty slick.
No comments:
Post a Comment