Skip Navigation Links



Translate this page now :



»Programação
»Programação.NET
»Banco de Dados
»Webdesign
»Office
» Certificações Microsoft 4
»Treinamentos4
»Programação 4
»Webdesign«
»Office & User Tips«
»Grupos de UsuĆ”rios
»CĆ©lulas AcadĆŖmicas«
intcontpiada : 118
Viciado
Você já está cadastrado e participa do grupo de usuários de sua cidade ? Se não, comente o porque.
 
 
FaƧa um pequeno teste com 10 questƵes de VB
.:.
Teste seus conhecimentos em Visual Basic, SQL Server e ASP 3.0 com nossas provas on-line
.:.
Aprimore seus conhecimentos em programaĆ§Ć£o com nosso treinamento on-line de lĆ³gica de programaĆ§Ć£o
.:.
Veja nosso calendƔrio de treinamentos
Gostou da PƔgina?
Então

para um amigo!

Pesquisa personalizada
Pesquisar Dicas:

 






Os Mistérios do ViewState

O Viewstate é um sujeito frequentemente muito mal compreendido pelos desenvolvedores. Desenvolvedores vindos de tecnologias ultrapassadas, quando olham para o source de uma página ASP.NET, acham que o source está "cheio de lixo" e que eles faziam melhor se fizessem manualmente.

O problema é que cada um desses "lixos" como eles chamam, tem um motivo muito bom para existir em termos de metodologia de desenvolvimento e um desenvolvedor que realmente tente fazer tudo "manualmente" vai acabar se vendo obrigado a re-criar tudo isso que chama de lixo, porém com qualidade ainda inferior.

Demonstração

Vamos então analisar o funcionamento - e utilidade - do ViewState.

Siga os seguintes passos :

1) Crie um site web

2) Insira uma textbox chamada txtValor

3) Insira um botão chamado cmdCalcular

4) Insira um label chamado lblResultado

5) No evento cmdCalcular_Click programe o seguinte :

   1: lblresultado.text = txtvalor.text * 0.92

 

6) Rode a página

Quando executamos a página o processamento ocorre normalmente : A classe da página é criada, as classes dos web controls são criadas, cada um gera seu HTML e tudo é destruido da memória do servidor.

7) Digite um valor na caixa e clique no botão

Da mesma forma que antes, a página é instanciada, as classes dos web controls são instanciadas, porém desta vez existe um evento click para ser processado e isso acontece. Após o processamento o HTML é gerado novamente e tudo volta a ser destruido.

Porém desta vez a textbox já vem preeenchida. Como a nova instância da textbox criada no servidor sabe que deve vir preenchida ?

Isso é simples : Todos os web controls, quando são instanciados no inicio do processamento de uma página, analisam o pacote HTTP que é passado para o servidor. A Textbox neste caso observou no pacote HTTP que existia um valor dentro da textbox e desta forma manteve o mesmo valor.

8) Ao lado do botão cmdCalcular, insira um novo botão, cmdCor

9) No click do botão cmdCor, insira o seguinte código :

   1: txtValor.BackColor = Drawing.Color.Red

 

10) Execute a aplicação

11) Digite um valor na caixa txtValor e clique no cmdCalcular

Tudo continua ocorrendo como antes

12) Clique no botão cmdCor

A caixa txtValor muda de cor, o que já era esperado, mas observe que o label lblResultado continua mantendo seu valor. O label é um simples texto impresso na página e por isso não é transmitido junto com o protocolo HTTP, então a questão é : Como a nova instância do label, criada no servidor, sabe o valor que o label tinha ?

13) Digite um novo valor em txtValor e clique novamente em cmdCalcular

O cálculo é realizado, mas a caixa de texto mantém a cor. Ficamos então com a mesma pergunta : A cor de uma caixa de texto não é naturalmente transmitida via HTTP, então como a nova instância da textbox no servidor sabe a cor com que a caixa de texto estava ?

O label e a textbox são exemplos de objetos que precisam manter suas informações através dos postbacks, ou seja, das idas ao servidor.

A forma que encontram para fazer isso é justamente algo que nós mesmos fariamos : Criando um campo hidden. A diferença é que todos os webControls da página mantém suas informações em um único campo hidden denominado ViewState ("__ViewState") e este campo é codificado (não criptografado, codificado) para não se tornar tão facilmente legível.

Resultado : Os webControls estão fazendo exatamente o que nós faríamos quando desejassemos manter informações entre as idas ao servidor, só que de uma forma bem mais aperfeiçoada.

 

A segurança do ViewState

Antes de falarmos da segurança do viewState é bom termos em mente que ele não foi feito para isso. Quer dizer : O objetivo do ViewState é manter os dados através dos postbacks e ele faz exatamente como nós faríamos - utilizando campos hidden. A segurança fornecida pelo viewstate é um recurso adicional que certamente não implementariamos por conta própria - mas o ASP.NET faz para nós.

A segurança do ViewState pode ser dividida em 2 partes : leitura do que está no viewstate e adulteração do viewstate.

Segurança de leitura

O ViewState é codificado, não criptografado, portanto sua segurança em relação a leitura é zero. Isso significa que você não deve armazenar nenhuma informação crítica dentro do viewstate, do contrário a informação estará comprometida.

Mas como, se ele parece tão ilegível ?

A codificação utilizada para gerar o viewstate é uma codificação conhecida e existem softwares na web que podem decifrar esta codificação, tornando as informações do viewstate perfeitamente legíveis.

Um exemplo é o ViewStateDecoder da Pluralsight :

Caso você deseje realmente tornar o viewstate ilegível é possível criptografar o viewstate através do uso do atributo ViewStateEncryptionMode na tag @page, porém criptografar o viewstate gera um impacto na performance da aplicação web

As opções do ViewStateEncryptionMode são as seguintes :

Always : Criptografar o ViewState

Never : Não Criptografar o viewstate

Auto : Por default, não criptografa. Porém web controls podem exigir a criptografia e neste caso ela será feita.

A configuração também pode ser feita através do web.config :

 

   1: <configuration> 
   2:     <system.web> 
   3:         <pages ViewStateEncryptionMode="Always" /> 
   4:     </system.web> 
   5: </configuration> 

 

A criptografia obviamente afeta a performance. Veja o resultado :

Sem criptografia :

Com criptografia :

Segurança contra adulteração

O viewState contém um código de criptografia hash para validar seu conteúdo. Desta forma, quando um postback acontece, o servidor verifica se o código hash é válido, garantindo que o viewstate não foi adulterado. Se o hash se mostrar inválido, a página não é executada.

Desta forma, apesar de não garantir que as informações do viewstate serão ocultas, temos a garantia de que as informações do viewstate não podem ser adulteradadas.

Importante

O hash do viewstate é gerado com uma chave auto-gerada no servidor. Assim sendo o hash do viewstate gerado por um servidor não é equivalente ao hash do viewstate gerado por outro servidor.

No ambiente web, um recurso frequentemente utilizado para garantir a escalabilidade da aplicação é o chamado Load Balance, ou seja, vários servidores executando a mesma aplicação parecendo ser um só. Nestes casos, para garantir que o hash dos servidores que participam do load balance seja compatível, é necessário que a chave de hash seja igualada através da configuração machineKey em todos os servidores envolvidos no load balance.

O mesmo acontece com a chave de criptografia caso o viewstate seja criptografado

 

Controlando o ViewState

Os webcontrols não podem ter todo o poder de decisão sobre guardar suas informações. Existem informações que podemos simplesmente não desejar guardar, como por exemplo a cor de uma textbox. Experimente realizar os seguintes passos :

14) Selecione a textbox e na janela de propriedades desligue a propriedade viewstate (false)

15) Execute a aplicação

16) Clique no botão cmdCor

A cor da textbox mudará

17) Digite um valor e clique no botão cmdCalcular

O cálculo será feito, mas a cor da textbox não será mantida.

Observe que o conteúdo da textbox foi mantido, mas a cor não. Faz parte das características do protocolo HTTP manter o conteúdo da textbox, mas a cor depende do viewstate para ser mantida e este foi desligado.

Veja o viewstate antes e depois de desligar o viewstate :

Antes :

Depois :

 

Armazenagem de dados no ViewState

Além dos webControls armazenarem suas informações no viewstate, também podemos armazenar nossas informações personalizadas no viewstate. Porém devemos estar atentos ao fato que o nome das "variáveis" criadas no viewstate são sensíveis a caixa de letra.

A forma mais otimizada - em termos de manutenção da aplicação - de armazenar dados no viewstate é criando uma propriedade e fazendo com que todo o acesso ao viewstate fique encapsulado dentro da propriedade

Siga estes passos para fazer um exemplo :

1) Crie uma nova página

2) Insira uma textbox chamada txtNome na página

3) Insira um botão chamado cmdAdicionar ao lado da textbox, configurando o text para "Adicionar"

4) Insira uma listbox chamada lstNomes abaixo da textbox

5) No código da página, crie a seguinte propriedade :

   1: Public ReadOnly Property Nomes() As List(Of String)
   2:     Get
   3:         If IsNothing(ViewState("nomes")) Then
   4:             ViewState("nomes") = New List(Of String)
   5:         End If
   6:         Return (ViewState("nomes"))
   7:     End Get
   8: End Property

 

   1: list<string> nomes
   2: {
   3:   get
   4:     {
   5:       if (viewstate["nomes"]==null)
   6:         {
   7:            viewstate["nomes"]=new list<string>();
   8:       }
   9:         return (list<string>)viewstate["nomes"];
  10:     }
  11: }

 

6) Crie a sub "Exibir" da seguinte forma :

   1: Public Sub Exibir()
   2:     lstNomes.DataSource = Nomes
   3:     lstNomes.DataBind()
   4: End Sub

 

   1: public void exibir()
   2: {
   3:      lstnomes.DataSource=nomes;
   4:      lstnomes.databind();
   5: }

 

7) Programe o page_load para chamar o exibir :

   1: Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
   2:     Exibir()
   3: End Sub

 

   1: protected void Page_Load(object sender, EventArgs e)
   2: {
   3:    exibir();
   4: }

 

8) Programe o click do botão da seguinte forma :

   1: Protected Sub cmdAdicionar_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdAdicionar.Click
   2:     Nomes.Add(txtNome.Text)
   3:     Exibir()
   4:     txtNome.Text = ""
   5: End Sub

 

   1: protected void cmdAdicionar_Click(object sender, EventArgs e)
   2: {
   3:     Nomes.Add(txtnome.text);
   4:     exibir();
   5:     txtnome.text="";
   6: }

 

9) Teste a aplicação

Conforme adicionar nomes na textbox e clicar no botão os nomes serão inseridos - e mantidos - na listbox, na verdade ficando guardados no viewstate. A propriedade "Nomes" que foi criada garante que as referências ao viewstate estarão todas no mesmo local do código - a propriedade

 

Armazenagem do ViewState

O ViewState não precisa ser obrigatoriamente um campo hidden, esta é apenas a forma default de armazenagem do viewstate. Um webform possui uma estrutura adequada para permitir a personalização de armazenagem do viewstate.

A personalização de armazenagem mais comum é quando os valores do viewstate são armazenados em sessão. Porém este é apenas um exemplo, comum por ser fácil, pois o desenvolvedor pode utilizar a forma de armazenagem que desejar.

Trocar o local de armazenagem do viewstate significa trocar a "peso" da aplicação de lugar : Com o viewstate como campo hidden o peso fica na transmissão do HTML entre o servidor e o client. Com o viewstate sendo passado para ambiente de sessão o peso passa a estar na memória do servidor.

Armazenando o ViewState em Sessão

Existem 2 métodos na página nos quais devemos fazer overrides para fazer a gravação do viewstate em sessão :

LoadPageStateFromPersistenceMedium : Lê o viewstate e devolve para o ASP.NET. É uma function.

SavePageStateToPersistenceMedium : Recebe o valor de viewstate da página e grava no local desejado

Fazendo o overrides nestes 2 métodos podemos gravar o viewstate em qualquer local que desejarmos. Vamos fazer um exemplo gravando o viewstate em sessão.

Sem dúvida que existem diversos algorítimos que poderiam ser utilizados para esta gravação. Vou fazer da forma mais simples, uma variável de sessão por página. Já vi exemplos de gravação em sessão com datatable, apenas testes práticos poderiam demonstrar ganhos e perdas.

1) Programe o SavePageStateToPersistenceMedium

   1: Protected Overrides Sub SavePageStateToPersistenceMedium(ByVal state As Object)
   2:     Session("viewstate" & Request.Url.ToString) = state
   3: End Sub

 

   1: protected overrides SavePageStateToPersistenceMedium(Object state)
   2: {
   3:     Session["viewstate" + Request.Url.ToString()]=state;
   4: }

 

A variável de sessão precisa ter o nome da página concatenado a seu nome base, como no exemplo. Isso porque o usuário pode ter várias páginas abertas na mesma sessão (várias abas) e não pode receber erro de viewstate nesta situação

2) Programe o LoadPageStateFromPersistenceMedium

   1: Protected Overrides Function LoadPageStateFromPersistenceMedium() As Object
   2:     If Not Me.IsPostBack Then
   3:         Session("viewstate" & Request.Url.ToString) = String.Empty
   4:     End If
   5:     Return Session("viewstate" & Request.Url.ToString)
   6: End Function

 

   1: protected overrides object LoadPageStateFromPersistenceMedium()
   2: {
   3:     if (!this.ispostback)
   4:         {
   5:             Session["viewstate" + Request.Url.ToString()]=string.empty;
   6:         }
   7:     return Session["viewstate" + Request.Url.Tostring()];
   8: }

 

A variável de sessão apenas é recuperada se estivermos em um postback. Se não for postback, limpamos a variável de sessão. Isso é importante pois o usuário pode já ter visitado esta página na mesma sessão e ter um viewstate guardado da visita anterior.

Compactação do ViewState

A compactação do ViewState também é uma possibilidade, utilizando os algorítimos de compactação do .NET. Porém também é apenas uma forma de mudar o "peso" de lugar : O que se economiza em tráfego se consome em processamento.

 

 





Envie seus comentįrios sobre este artigo

Nome :

E-mail :

Comentários :


Avise-me quando houverem novos comentįrios nesta pįgina

Veja abaixo os comentários já enviados :

Nome : E-Mail :
Nome : WIUjr34nuQH3 E-Mail : 6ucfq9uy@outlook.com
sotck image central on January 31, 2012 Greetings I am so glad I found your wlobeg, I really found you by mistake, while I was researching on Askjeeve for something else, Anyhow I am here now and would just like to say thank you for a fantastic post and a all round thrilling blog (I also love the theme/design), I don’t have time to go through it all at the minute but I have saved it and also added in your RSS feeds, so when I have time I will be back to read a great deal more, Please do keep up the fantastic work.
Nome : vypwyUxU E-Mail : adxh9buf60@mail.com
Yup, that shloud defo do the trick!
Nome : oHNPtYxvrU E-Mail : ehlahzpi@yahoo.com
N&rsquo;importe quoi, faut vraiment être trop con pour laisser couler l&rsquo;eau quand on se brosse les des#r&t8230;.C&snquo;est ça qu&rsquo;ils appellent &laquo;&nbsp;retourner à l&rsquo;age de pierre&nbsp;&raquo; les anti-écolos ? Fermer le robinet quand on se brosse les dents ?

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Conheça mais sobre o nosso site :

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::



Quer saber mais?
Faça um curso na Búfalo Informática, Treinamento e Consultoria e
Prepare-se para o Mercado!
Veja o que a Búfalo tem para você.

ļæ½ BĆŗfalo InformĆ”tica, Treinamento e Consultoria - Rua Ɓlvaro Alvim, 37 Sala 920 - CinelĆ¢ndia - Rio de Janeiro / RJ
Tel.: (21)2262-1368 (21) 9240-5134 (21) 9240-7281 e-Mail:
contato@bufaloinfo.com.br