O ViewState é um campo oculto especial
tratado pelo ASP.NET para manter o estado dos controles. Dependendo da
quantidade de controles que houver na página e da quantidade de informações que
for mantida entre um PostBack e outro nesses controles, o tamanho da
página pode aumentar muito. Desde o lançamento do .NET 2.0 que existe um namespace
chamado System.IO.Compression que possui métodos para trabalhar com GZip
tanto em GZipStream quanto em DeflateStream. Assim como no meu
artigo anterior (Gerando
JavaScript do lado do servidor com ASP.NET) onde definimos uma classe que
herda da System.Web.UI.Page, podemos definir esta mesma classe, com
vários métodos como o "ExibirMensagem", métodos de validação, entre
outros e definir também a com compactação do ViewState da seguinte forma:
private
ObjectStateFormatter _formatter = new ObjectStateFormatter();
// Comprime o ViewState
protected override void
SavePageStateToPersistenceMedium(object viewState)
{
try
{
MemoryStream
ms = new MemoryStream();
_formatter.Serialize(ms, viewState);
byte[]
viewStateArray = ms.ToArray();
ClientScript.RegisterHiddenField("__COMPRESSEDVIEWSTATE",
Convert.ToBase64String(Compressor.Compress(viewStateArray)));
}
catch { }
}
// Descomprime o ViewState
protected override object
LoadPageStateFromPersistenceMedium()
{
object obj = new object();
try
{
string
vsString = Request.Form["__COMPRESSEDVIEWSTATE"];
byte[] bytes
= Convert.FromBase64String(vsString);
bytes =
Compressor.Decompress(bytes);
obj =
_formatter.Deserialize(Convert.ToBase64String(bytes));
}
catch { }
return obj;
}
// Joga o ViewState para o final da página e otimiza o HTML gerado
protected override void Render(System.Web.UI.HtmlTextWriter
writer)
{
try
{
StringWriter
stringWriter = new StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
base.Render(htmlWriter);
string html
= stringWriter.ToString();
string
newHtml = string.Empty;
int startPoint = html.IndexOf("<input type=\"hidden\"
name=\"__COMPRESSEDVIEWSTATE\"");
if
((startPoint >= 0))
{
int endPoint = (html.IndexOf("/>", startPoint) + 2);
string viewStateInput = html.Substring(startPoint, (endPoint - startPoint));
newHtml = html.Remove(startPoint, (endPoint - startPoint));
int formEndStart = (newHtml.IndexOf("</form>"));
if ((formEndStart >= 0)) { html = newHtml.Insert(formEndStart,
viewStateInput); }
}
html =
Regex.Replace(html, ">\\s+<", "><");
writer.Write(html);
}
catch
{
Response.Redirect(Request.Url.ToString());
}
}
Portanto, utilizando uma classe
"Principal" herdando de System.Web.UI.Page e toda página na
sua aplicação herdando desta classe, podemos definir alguns métodos que serão
utilizados em todo o site e também algumas manipulações com o ViewState,
como compactação e deslocamento para o final da página, ainda removendo os
espações em excesso do código-fonte gerado pela página.
Resultado final do HTML
(...)
<input
type="hidden" name="__COMPRESSEDVIEWSTATE"
id="__COMPRESSEDVIEWSTATE" value="
H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/
SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577
733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/
Iv7vX/M3nf2mv26yvfvg/sMHO/f2Pv1NZ7/Nr3WOf36tX5v+/fV+rV/3N/1tfq1f"
/></form></body</html>
Bingo! ViewState comprimido e no final da páginae ainda com o código
otimizado (sem espaços em branco).
Até a próxima. Abraços