Desenvolvimento - ASP. NET

Compactação de ViewState em ASP.NET

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.

por Rodolfo Paoni



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

Rodolfo Paoni

Rodolfo Paoni - Rodolfo Paoni - Desenvolvedor .NET - Twitter: @rodolfopaoni