Lição 1: Understanding the ASP.NET Life Cycle and Handling Events

A primeira lição do capítulo 3 explica sobre o ciclo de vida da página e dos controles.

De início a lição começa explicando sobre os eventos mais comuns que são manipulados no arquivo Global.asax:
  • Application_Start: É executado quando a aplicação é iniciado no servidor, muito comum quando é feito o acesso do primeiro usuário.
  • Application_End: Quando a aplicação é finalizada. Pode ocorrer quando você para a aplicação pelo IIS ou quando é feito o servidor é reiniciado ou desligado.
  • Application_Error: Como o nome já explica é executado quando ocorre um erro na aplicação.
  • Application_LogRequest: É executado quando é feita uma requisição a aplicação, é usado para gravar informações especificas da requisição.
  • Application_PostLogRequest: É executado quando é concluida uma requisição feita ao sistema.
Como uma sessão que é criado por usuário é possível criar uma sessão que é utilizada por toda aplicação. Basta substituir o Session por Application, é como uma sessão, mas ao invés de ser enxergada por um único usuário é enxergada por todos os usuários da aplicação.

Em seguida na lição inicia a explicação do ciclo de vida da página, com certeza a maior dificuldade para programadores de aplicações windows que migram para o ambiente web, pois não estão acostumados com essa situação.

Os eventos mais comuns e em ordem de execução de uma página são os seguintes:
  • PreInit: É o primeiro evento que o desenvolvedor pode manipular de uma página, é muito utilizado para definir valores de Master Page ou Temas em tempo de execução. Caso não utilize Master Page é neste evento que você pode criar controles dinamicamente.
  • Init: Este evento é executado depois que todos controles foram instanciados, aqui você pode alterar os valores de iniciação dos controles. Caso utilize Master Page é neste evento que deve adicionar os controles dinamicamente.
  • InitComplete: Executado quando todas as inicializações estiverem completas.
  • PreLoad: Executado antes da viewstate ser carregada e antes de ocorrer o processo de Postback. Necessário quando você precisa que os controles estejam iniciados e antes da viewstate ser restabelecida.
  • Load: A página está estável e iniciada. O Evento Load da página é chamada primeiramente, em seguida todos os eventos Load dos controles são executados hierarquicamente.
  • LoadComplete: Neste evento todos os controles são carregados.
  • PreRender: Este evento ainda permite que alterações finais aos controles. Ocorre depois dos eventos de postback ter ocorridos, e ainda a viewstate não foi salva, ainda permitindo alterações.
  • SaveStateComplete: Neste evento a viewstate esta pronta. Qualquer alteração feita neste momento ou depois serão ignoradas. Este evento é util quando você precisa justamente que a viewstate esteja pronta.
  • Render: O Render é um método e não um evento, o asp.net chama este método para cada controle. Este método gera os códigos html e todos os outros necessários para exibição da página ao cliente.
  • Unload: Este evento é utilizado para liberação de recursos, até pode ser executado manualmente mas é um processo pouco comum.
Após explicar os principais eventos do ciclo de vida da página. A lição explica como criar um controle em tempo de execução. Código simples, única resalva é utilizar o evento Page_PreInit (quando não usar Master Page) ou Page_Init (quando usar Master Page):

protected void Page_PreInit(object sender, EventArgs e)
{

    // Create instances of the controls
    Label FeedbackLabel = new Label();
    TextBox InputTextBox = new TextBox();
    Button SubmitButton = new Button();
    // Assign the control properties
    FeedbackLabel.ID = "FeedbackLabel";
    FeedbackLabel.Text = "Please type your name: ";
    SubmitButton.ID = "SubmitButton";
    SubmitButton.Text = "Submit";
    InputTextBox.ID = "InputTextBox";
    // Create event handlers
    SubmitButton.Click += new System.EventHandler(SubmitButton_Click);
    // Add the controls to a Panel
    Panel1.Controls.Add(FeedbackLabel);
    Panel1.Controls.Add(InputTextBox);
    Panel1.Controls.Add(SubmitButton);
}


protected void SubmitButton_Click(object sender, EventArgs e)
{
    // Create an instance of Button for the existing control
    Button SubmitButton = (Button)sender;
    // Update the text on the Button
    SubmitButton.Text = "Submit again!";
    // Create the Label and TextBox controls
    Label FeedbackLabel = (Label)FindControl("FeedbackLabel");
    TextBox InputTextBox = (TextBox)FindControl("InputTextBox");
    // Update the controls
    FeedbackLabel.Text = string.Format("Hi, {0}", InputTextBox.Text);
}


A lição explica como criar os eventos da página, no caso do vb você deve utilizar os dois ComboBox que estão na parte superior no arquivo de código. E no caso do c#, basta escrever o código, pois a propriedade AutoEventWireup por padrão é true, não necessitando mais nenhuma associação.

Outro processo comum utilizado pelos desenvolvedores e explicados é o PostBack automático. Alguns controles como o botão executam o postback automaticamente quando seu evento é acionado. Mas no caso do evento TextChanged do TextBox por exemplo ele não executa o PostBack automaticamente, é necessário alterar a propriedade AutoPostBack para true, caso não faça isso, o evento TextChanged só será executado quando outro controle executar o PostBack no formulário como por exemplo um clique do botão.

Neste caso como ocorre: O usuário alterou o texto do textBox, nada acontece pois a propriedade esta como false, em seguida o usuário clica no botão. O primeiro evento a ser executado é o TextChanged que estava aguardando um postback ocorrer, em seguida é executado o evento clique do botão.

Se quiser que o TextChanged seja executado assim que o texto seja alterado altere a propriedade AutoPostBack para true.

Lição 2: Using Client-Side State Management

Esta lição mostra as principais maneiras de gerenciamento de estado do lado do cliente, desta forma economizando recursos do servidor.

As principais técnicas são:
  • View state: O asp.net utiliza para controlar os valores dos controles entre as requisições da página.
  • Control state: É possível persistir informações específicas do controle sem utilizar a View State, é muito utilizado em casos de controles personalizados.
  • Hidden fields: Como a View State este campo fica no html mas não é renderizado para o usuário
  • Cookies: Um cookie fica armazenado no navegador do usuário, para cada requisição que é enviada para o servidor o valor do cookie é enviado também, é a maneira mais recomendada quando é necessário acessar este valor em diferentes páginas do mesmo domínio.
  • Query strings: É um valor informado pela url da página, fica visível ao usuário na barra de endereço do browser.
Antes de explicar sobre cada uma dessas formas de persistir os dados do lado do cliente, a lição explica vantagens e desvantagens de persistir os dados do lado do servidor e do lado do cliente.

Persistindo os dados no cliente, as vantagens são:
  • Melhor Escalabilidade: Caso utiliza-se do lado do servidor, a cada acesso de um cliente/usuário aumenta o uso de memória do servidor. Jogando esta carga para o cliente para um irá absorver o seu acesso e irá ter um grande consumo de recurso do servidor.
  • Suporte por Múltiplos Servidores: Caso você necessite de uma grande arquitetura de servidores, obter as informações do cliente que estão no browser será possível por qualquer servidor sem fazer um balanceamento de carga inteligente. Ou seja caso o usuário mude de servidor no meio de uma sessão, basta o servidor acessar os dados que estão no browser.
Vantagens de persistir os dados no servidor:
  • Melhor Segurança: A menos que você assine digitalmente as informações que estão no cliente, qualquer um pode alterar os dados armazenados. Ou seja nunca armazene no cliente dados confidenciais como senhas e níveis de acesso.
  • Redução de Banda: Os dados estando no servidor não é necessário o envio e recebimento dessas informações, os dados estando no cliente a cada requisição os dados são enviados ao servidor, utilizando banda do cliente e do seu servidor. O conselho é armazenar pequenas informações no cliente.
Qual usar? Agora é você que decide com bases nessas informações. Se você tiver uma aplicação com poucos usuário e informações sigilosas utiliza recursos do servidor. Se quer ganhar performance em sua aplicação utilize as duas formas, sabendo quando usar uma ou outra.

View State

View State é um mecanismo do asp.net para armazenar dados de um usuário entre as requisições da mesma página. A view state não é armazenada no servidor, fica no código html da página, ela armazena estados de exibição dos controles que são acessados entre cada requisição, não consumindo assim recursos do servidor.

Caso não desabilite a View State é padrão de todas as páginas. Um exemplo, quando faz uma consulta o servidor retorna os dados e o formulário é preenchido, quando o usuário alterar algum campo e clicar no botão gravar por exemplo, caso haja um erro no envio desses dados ao servidor, as informações já digitadas não será perdidas, pois os valores armazenados na View State permaneceram.

A View State é armazenada da seguinte forma no código html:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwULLTEzNjkxMzkwNjRkZAVvqsMGC6PVDmbCxBlPkLVKNahk" />


Caso o valor seja muito grande a View State é quebrada em 2 ou quantas for necessária para armazenar  o valor. Repare que o valor é um hash e é compactado para oferecer maior segurança e maior performance que um campo hidden comum.

Como a View State ficar no código html, o usuário consegue modificar estes valores, porém o asp.net possui um código de autenticação que consegue validar se a View State foi alterada ou não.

Caso queira maior segurança para sua aplicação é possível criptografar suas View State através de uma configuração do Web.config:

<configuration>
<system.web>
<pages viewStateEncryptionMode="Always"/>
</system.web>
</configuration>


Só que desta forma irá perder um pouco de performance pois toda vez terá que ser feito a criptografia e a descriptografia. Uma alternativa seria criptografar somente as View State que forem realmente necessárias, colocando a diretiva diretamente na página:

<%@ Page Language="C#" AutoEventWireup="true" ViewStateEncryptionMode="Always"%>

Como disse por padrão a View State esta habilitada em todas as páginas e para todos os controles. Devido ao trafego de envio e recebimento de informações da View State você pode optar por desabilita-la.

Caso a página seja acessada por usuário de conexões lentas e sejam páginas com um grande número de controles, a lição especifica mais de 10 controles, vale a pena pensar na hipóteses de desabilita-la. Você deve controlar os dados que são armazenados na View State, para controlar a nível de página utilize as propriedades Page.EnableViewState e Page.ViewStateMode, para controles utilize Control.EnableViewState e Control.ViewStateMode.

A propriedades ViewStateMode é nova no FrameWork 4 e só terá efeito caso a propriedades EnableViewState esteja como true. Por padrão a ViewStateMode da Página tem o valor de Enabled e a propriedades ViewStateMode dos controles herdam o valor atribuido a propriedade da página.


Caso você defina o EnableViewState como falso a View State estara desabilitada independentemente do valor atribuido a propriedade ViewStateMode. Porém se manter a propriedades EnableViewState como verdadeira pode alterar a propriedade ViewStateMode para desabilitada. Em resumo trabalhe com a propriedade ViewStateMode. 

A lição tem uma tabela que ilustra como usar essas propriedades de forma mais simples:

Desabilitar a View State de uma página, porém habilitar de um controle especifico:
Page.Enable ViewState: True, Page.ViewState Mode: Disabled, Controle.Enable ViewState: True, Control.ViewState Mode: Enabled

Desabilitar a View State de uma página, e desabilitar de um controle especifico:
Page.Enable ViewState: True, Page.ViewState Mode: Disabled, Controle.Enable ViewState: False, Control.ViewState Mode: Disabled

Habilitar a View State de uma página, porém desabilitar de um controle especifico:
Page.Enable ViewState: True, Page.ViewState Mode: Enabled, Controle.Enable ViewState: False, Control.ViewState Mode: Disabled

Habilitar a View State de uma página, e de um controle especifico:
Page.Enable ViewState: True, Page.ViewState Mode: Enabled, Controle.Enable ViewState: True, Control.ViewState Mode: Enabled

Você pode desabilitar a View State de todo o projeto diretamente no web.config:
<configuration>
<system.web>
<pages enableViewState="false">
</system.web>
</configuration>


Para ler e escrever dados em uma View State é simples:


this.ViewState.Add("MyData", "some data value"); //Escrevendo
string myData = (string)ViewState["MyData"]; //Lendo


Hidden Fields


Não tenho muito o que explicar sobre Hidden Fields, são parecidos com a View State, são campos que armazenam valores, ficam no código html da página porém não são exibidos ao usuário. Só é possível ve-los acessando o código fonte da página.


Cookies


Outra prática comum pra quem já é desenvolvedor web. Cookies armazenam valores no browser do cliente e a cada requisição ao servidor os valores são enviados. A vantagem do uso de cookies sobre o uso de View State e Hidden Fields é que os cookies podem ser acessados de qualquer página desde que esteja no mesmo dominio em que foi criado.


É possível ainda configurar seu tempo de vida e seu dominio. Escrever e ler dados de um cookie é simples:
Response.Cookies.Add(New HttpCookie("userId", userId))

E para ler o valor:
Request.Cookies("userId").Value

Exemplo de código:
// Verifica se o cookie ja existe
if (Request.Cookies["lastVisit"] != null)
    // Encode the cookie in case the cookie contains client-side script
    Label1.Text = Server.HtmlEncode(Request.Cookies["lastVisit"].Value);
else
    Label1.Text = "No value defined";
// Define o valor do cookie
Response.Cookies["lastVisit"].Value = DateTime.Now.ToString();
Response.Cookies["lastVisit"].Expires = DateTime.Now.AddDays(1);


Query Strings

Outra prática comum em qualquer linguagem web. Query String é uso de parâmetros via URL. É formado de um parâmetro e seu valor correspondente. O primeiro parâmetro deve ser informado após o ponto de interrogação ?  os parâmetros seguintes com o &.


Exemplo: http://www.quintelab.com.br/bruno.aspx?id=1&nome=bruno


No exemplo acima o primeiro parâmetro é o ID e o segundo é o NOME. Para ler esses parâmetros informados via QueryString basta:


string id = Request.QueryString["id"].ToString();
string nome = Request.QueryString["nome"].ToString();

Alguns cuidados devem ser tomados, os navedores suportam 2083 caracteres. E fica fácil para qualquer usuário alterar os valores contidos na url. Este caso é muito usado por exemplo para o envio de url via e-mail que quando acessadas irã ser direcionadas já para um produto especifico.

Lição 3: Using Server-Side State Management

Do contrário da lição 2, a lição 3 mostra as técnicas de gerenciamento de sessão no servidor. Você deve gerenciar os estados no servidor quando existe uma quantidade grande de dados e se torna oneroso a ida e vinda desses dados entre o cliente e o servidor. Outro grande motivo é a segurança, podemos trabalhar com dados sigilosos que não podem correr o risco de ficar disponível na máquina do cliente.

O asp.net disponibiliza duas formas de gerenciar pelo servidor, essas formas já foram citadas em lições anteriores. Os métodos são Application State e Session State.

O primeiro é global, ou seja, os dados são acessados por todos os usuário em qualquer página. Os dados armazenados no Application State são os mesmos para todos os usuários. Já o segundo método Session State é único por cada usuário, cada usuário tem a sua sessão, da mesma forma que o Application State os dados armazenados em Session State são acessados em qualquer página.

Application State

Os dados armazenados no Application State são globais e podem ser acessados em qualquer requisição de qualquer página. A classe HttpApplicationState é um dicionário de chave e valor e pode ser acessado pelo nome do chave. Os dados armazenados no Application State não são permanentes, no momento em que a aplicação é reiniciada, por exemplo quando o IIS ou o servidor é iniciado os dados armazenados neste sessão são perdidos.

Session State

 Os dados armazenados com Session State também podem ser acessados de qualquer página, a grande diferença é que é único por usuário (browser). Por padrão esses dados são armazenados na memória do servidor, mas é possível  é configurar para utilizar cookies, em State Serve ou em um banco de dados.


De forma similar ao Application State, o Session State é um dicionário de chave e valor, como demonstra o código:


// Caso a sessão não exista
if (Session["lastVisit"] != null)
{
    Label1.Text = ((DateTime)Session["lastVisit"]).ToString();
}
else
{
    Label1.Text = "Session does not have last visit information.";
}
// Definindo um valor para a sessão
Session["lastVisit"] = DateTime.Now;


Caso queira desabilitar o uso de sessões pode fazer no web.config:
<configuration>
<system.web>
<sessionState mode="off"/>
</system.web>
</configuration>


Ou  definir na diretiva da página no caso de desabilitar em páginas especificas, utilizando a propriedade EnableSessionState:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="_Default" EnableSessionState = "False"%>


É possível configurar a forma com que irá utilizar sua sessão:
  • InProc: é o modo padrão. É o que oferece melhor desempenho em relação as outras opções. No entanto ele fica limitado em cenários de balanceamento de carga entre servidores. Pois não terá como garantir que um usuário comece e termine seu processo no mesmo servidor.
  • StateServer: Nesta configuração os dados armazenados na sessão não são perdidos quando a aplicação é reiniciada, e neste cenário é possível fazer o compartilhamento entre servidores. O StateServer é um serviço do asp.net que esta em qualquer máquina que possua o FrameWork instalado. Este serviço não é configurado para iniciar automaticamente e sim manualmente, por isso deve ser feito essa mudança para que inicie automaticamente caso deseja usar.
  • SQLServer: Tem os mesmos benefícios do StateServer, armazena os dados quando a aplicação é iniciada e  pode ser utilizado em vários servidores. Em hardware idêntico o StateServer supera o SQLServer, porém o SQLServer oferece integridade dos dados mais robustos e capacidade de relatórios.
  • Custom: Permite que você especifique uma sessão personalizada, necessitando do código para implementar seu armazenamento personalizado.
  • Off: Desativa as Sessões, deve utilizar esta opção caso queira desabilitar sessões.
Assim se encerra o capítulo III.

Abraços...