Na primeira parte deste artigo mostrei como compactar o ViewState em ASP.NET e neste artigo mostro a mesma técnica, porém colocando estes valores na Session. Existem vantagens e desvantagens com relação à essa abordagem, mas o código da página fica mais limpo e além disso, os valores na Session ficam compactados.
Esta classe de compressão foi omitida na primeira parte do artigo, pois o foco era mais na questão da sobreescrita dos métodos de criação e carregamento do ViewState do que na compactação em si. Aqui a apresento a classe na íntegra e a técnica do deslocamento deste resultado para a Sessão.
public static class Compressor
{
public static byte[] Compress(byte[] data)
{
try
{
using (MemoryStream output = new MemoryStream())
{
using (GZipStream gzip = new GZipStream(output, CompressionMode.Compress))
{
gzip.Write(data, 0, data.Length);
gzip.Close();
return output.ToArray();
}
}
}
catch
{
return new byte[0];
}
}
public static byte[] Decompress(byte[] data)
{
try
{
using (MemoryStream input = new MemoryStream())
{
input.Write(data, 0, data.Length);
input.Position = 0;
using (GZipStream gzip = new GZipStream(input, CompressionMode.Decompress))
{
using (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();
}
}
}
}
catch
{
return new byte[0];
}
}
}
// Página que Herda de System.Web.UI.Page e que será a base para as páginas criadas.
// Elas herdarão desta classe e não diretamente de Page
#region Compactação e otimização de VIEWSTATE
private ObjectStateFormatter _formatter = new ObjectStateFormatter();
// Comprime o VIEWSTATE e o coloca na Session
protected override void SavePageStateToPersistenceMedium(object viewState)
{
try
{
MemoryStream ms = new MemoryStream();
_formatter.Serialize(ms, viewState);
byte[] viewStateArray = ms.ToArray();
Session[string.Format("VIEWSTATE{0}", Request.Url.ToString())] =
Convert.ToBase64String(Compressor.Compress(viewStateArray));
}
catch { }
}
// Recupera o VIEWSTATE da Session e o descomprime
protected override object LoadPageStateFromPersistenceMedium()
{
try
{
byte[] bytes = Convert.FromBase64String(
Session[string.Format("VIEWSTATE{0}", Request.Url.ToString())].ToString());
bytes = Compressor.Decompress(bytes);
return _formatter.Deserialize(Convert.ToBase64String(bytes));
}
catch
{
return new object();
}
}
// Otimiza o HTML gerado, removendo os espaços desnecessários
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
try
{
StringWriter stringWriter = new StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
base.Render(htmlWriter);
string html = Convert.ToString(stringWriter);
html = Regex.Replace(html, ">\\s+<", "><");
writer.Write(html);
}
catch
{
Response.Redirect(Request.Url.ToString());
}
}
#endregion
Resultado no HTML:
<input type="hidden" name="__VIEWSTATE" id="
__VIEWSTATE" value="" />
Espero ter ajudado,
Abraços