domingo, 12 de julho de 2015

ASP.NET - Persistindo valores entre Web Forms




Quando começamos a programar para web, uma das dúvidas mais freqüentes é: Como devemos persistir valores entre Web Forms? Praticamente a maioria dos softwares há a necessidade de recuperar valores entre Formulários, em se tratando de Asp.Net seriam os denominados Web Forms. Por exemplo, Imaginem a seguinte situação, temos uma página onde os usuários irão realizar um Cadastro de Clientes e na página seguinte deveremos transportar estes mesmos dados para um processamento, onde os dados deverão ser armazenados e “lidos”. Onde ficarão armazenados estes dados? Como devemos tratá-los? Este artigo irá abordar as diversas formas de persistirem estes valores.  Temos diversos artifícios para trabalhar, como por exemplo:
  • Variáveis de sessão (Session)
  • QueryString
  • Método Server.Transfer
  • Classe HttpContext
Gostaria de exemplificar de uma forma simples todas as técnicas acima descritas. Antes de iniciarmos iremos criar um projeto base para o aprendizado. Para isto abra o Microsoft Visual Studio e crie uma página do Zero, adicionando um Web Form padrão (para Enviar os dados) e no meu caso achei melhor criar um Web Form para cada tipo de técnica citada anteriormente. Abaixo deixo uma sugestão de lay-out para Envio e Recebimento.
Na Figura 01 foram adicionados alguns TextBoxs, como: Nome, Endereço, Cidade, Estado, Tipo (Estes são os campos que iremos passar para a Página seguinte). Foram adicionados um botão para cada técnica, sendo: Session, QueryString, Server Transfer e HttpContext.

 
 
Figura 01: WebForm para Envio de dados.

Aproveito também para inserir o trecho principal do código em Aspx. Veja Listagem 01.

<form id="form1" runat="server">
    <table class="style1" width="380">
        <tr>
            <td colspan="2" style="text-align: center">
                <asp:Label ID="Label2" runat="server" ForeColor="#000066"
style="font-weight: 700; font-size: large; font-family: Arial, Helvetica, sans-serif; text-decoration: underline; font-style: italic;"
Text="ASP.NET - Persistindo valores entre Web Forms"></asp:Label>
            </td>
        </tr>
        <tr>
            <td colspan="2" style="text-align: center">
                <asp:Label ID="Label1" runat="server" ForeColor="#000066"
style="font-weight: 700; font-size: large; font-family: Arial, Helvetica, sans-serif"
                    Text="Página 01 - Enviar Dados"></asp:Label>
            </td>
        </tr>
        <tr>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
        </tr>
        <tr>
            <td>
<asp:Label ID="lblNome" runat="server" CssClass="style3" Text="Nome:"></asp:Label>
            </td>
            <td>
<asp:TextBox ID="txtNome" runat="server" CssClass="style4" Height="20px" Width="300px" ClientIDMode="Inherit"></asp:TextBox>
            </td>
        </tr>
        <tr>
            <td>
<asp:Label ID="lbEndereco" runat="server" CssClass="style3" Text="Endereço:"></asp:Label>
            </td>
            <td>
<asp:TextBox ID="txtEndereco" runat="server" CssClass="style4" Height="20px"
                    Width="300px"></asp:TextBox>
            </td>
        </tr>
        <tr>
            <td>
<asp:Label ID="lblCidade" runat="server" CssClass="style3" Text="Cidade:"></asp:Label>
            </td>
            <td>
<asp:TextBox ID="txtCidade" runat="server" CssClass="style4" Height="20px"
                    Width="200px"></asp:TextBox>
            </td>
        </tr>
        <tr>
            <td>
<asp:Label ID="lblEstado" runat="server" CssClass="style3" Text="Estado:"></asp:Label>
            </td>
            <td>
<asp:TextBox ID="txtEstado" runat="server" CssClass="style4" Height="20px" Width="150px"></asp:TextBox>
            </td>
        </tr>
        <tr>
            <td>
<asp:Label ID="lblTipo" runat="server" CssClass="style3" Text="Tipo:"></asp:Label>
            </td>
            <td>
<asp:DropDownList ID="dropTipo" runat="server" CssClass="style4" Height="20px"
                    Width="150px">
                    <asp:ListItem></asp:ListItem>
                    <asp:ListItem Value="F">Física</asp:ListItem>
                    <asp:ListItem Value="J">Jurídica</asp:ListItem>
                </asp:DropDownList>
            </td>
        </tr>
        <tr>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
        </tr>
        <tr>
            <td class="style2" colspan="2">
                <asp:Button ID="btnEnviarSession" runat="server"
                    style="font-family: Arial, Helvetica, sans-serif"
                    Text="Session" Width="260px" onclick="btnEnviar_Click" />
            </td>
        </tr>
        <tr>
            <td class="style2" colspan="2">
                <asp:Button ID="btnEnviarquerystring" runat="server"
                    style="font-family: Arial, Helvetica, sans-serif"
Text="QueryString" Width="260px" onclick="btnEnviarquerystring_Click" />
            </td>
        </tr>
        <tr>
            <td class="style2" colspan="2">
                <asp:Button ID="btnEnviarServerTransfer" runat="server"
                    style="font-family: Arial, Helvetica, sans-serif"
                    Text="Server Transfer" Width="260px"
                    onclick="btnEnviarServerTransfer_Click" />
            </td>
        </tr>
        <tr>
            <td class="style2" colspan="2">
                <asp:Button ID="btnEnviarHttpContext" runat="server"
                     style="font-family: Arial, Helvetica, sans-serif"
Text="HttpContext" Width="260px" onclick="btnEnviarHttpContext_Click" />
            </td>
        </tr>
        </table>
    <div>
  </div>
</form>

Listagem 01: Código da Página 01.
Abaixo o lay-Out da Página para receber os dados, contendo 5 Labels, sendo: Nome, Endereço, Cidade, Estado e Tipo. Cada componente irá receber o seu correspondente da página anterior. Ver Imagem 02.

 

 
Figura 02: WebForm de recebimento de dados.

O trecho principal do código em Aspx. Veja Listagem 02.

<form id="form1" runat="server">
    <table class="style1" width="380">
        <tr>
            <td colspan="2" style="text-align: center">
                <asp:Label ID="Label1" runat="server" ForeColor="#000066"
style="font-weight: 700; font-size: large; font-family:           Arial, Helvetica, sans-serif" Text="Página 02 - Receber Dados"></asp:Label>
            </td>
        </tr>
        <tr>
            <td class="style6">
                &nbsp;</td>
            <td>
                &nbsp;</td>
        </tr>
        <tr>
            <td class="style4" colspan="2">
                <asp:Label ID="lblInformativo" runat="server" ForeColor="#000066"
style="font-weight: 700; font-size: large; font-family: Arial, Helvetica, sans-serif">Session</asp:Label>
            </td>
        </tr>
        <tr>
            <td class="style6">
<asp:Label ID="lblNome" runat="server" CssClass="style3" Text="Nome:"></asp:Label>
            </td>
            <td>
<asp:Label ID="lblNomeRec" runat="server" CssClass="style5"></asp:Label>
            </td>
        </tr>
        <tr>
            <td class="style6">
<asp:Label ID="lblEndereco" runat="server" CssClass="style3" Text="Endereço:"></asp:Label>
            </td>
            <td>
<asp:Label ID="lblEnderecoRec" runat="server" CssClass="style5"></asp:Label>
            </td>
        </tr>
        <tr>
            <td class="style6">
<asp:Label ID="lblCidade" runat="server" CssClass="style3" Text="Cidade:"></asp:Label>
            </td>
            <td>
<asp:Label ID="lblCidadeRec" runat="server" CssClass="style5"></asp:Label>
            </td>
        </tr>
        <tr>
            <td class="style6">
<asp:Label ID="lblEstado" runat="server" CssClass="style3" Text="Estado:"></asp:Label>
            </td>
            <td>
<asp:Label ID="lblEstadoRec" runat="server" CssClass="style5"></asp:Label>
            </td>
        </tr>
        <tr>
            <td class="style6">
<asp:Label ID="lblTipo" runat="server" CssClass="style3" Text="Tipo:"></asp:Label>
            </td>
            <td>
<asp:Label ID="lblTipoRec" runat="server" CssClass="style5"></asp:Label>
            </td>
        </tr>
        <tr>
            <td class="style2" colspan="2">
                &nbsp;</td>
        </tr>
    </table>
    <div>
  </div>
</form>

Listagem 02. Código da Página 02.

 1-) Variáveis de Sessão

As variáveis de Sessão fornecem uma facilidade para armazenar informações na memória do servidor podendo suportar qualquer tipo de objeto. Para cada cliente, os dados da sessão são armazenados separadamente, o que significa que estes dados são armazenados em uma base por cliente. Umas de suas vantagens é que ao utilizá-la mantemos o estado do usuário e os dados de todo o aplicativo se comportando de forma totalmente segura e transparente.
Seguindo nosso exemplo, para armazenar os dados na sessão utilizaremos o código abaixo: Ver Listagem 03.

protected void btnEnviar_Click(object sender, EventArgs e)
{
     Session["nome"] = txtNome.Text;
     Session["endereco"] = txtEndereco.Text;
     Session["cidade"] = txtCidade.Text;
     Session["estado"] = txtEstado.Text;
     Session["tipo"] = dropTipo.SelectedItem;
     Response.Redirect("WebFormSession.aspx");
}
Listagem 03: Código para atribuir valores para as variáveis de sessão.

Podemos criar quantas variáveis de sessão que desejar e com o nome que acharmos melhor. Seguiremos o padrão, respeitando a ordem dos campos. Atribuímos os valores dos Componentes e logo em seguida com o comando “Response.Redirect” redirecionamos para a página onde iremos receber os valores destas variáveis. Iremos receber os dados no evento Page_Load() do WebForm, Ver Listagem 04.

protected void Page_Load(object sender, EventArgs e)
{
   if (!Page.IsPostBack)
   {
      lblNomeRec.Text = Session["nome"].ToString();
      lblEnderecoRec.Text = Session["endereco"].ToString();
      lblCidadeRec.Text = Session["cidade"].ToString();
      lblEstadoRec.Text = Session["estado"].ToString();
      lblTipoRec.Text = Session["tipo"].ToString();
   }
}
Listagem 04: Código para receber valores das variáveis de sessão.

Para receber os valores, devemos atribuir para a propriedade “Text” dos componentes. No caso estamos trabalhando com campos do tipo texto, mas ressalto que poderíamos receber um Objeto inteiro de qualquer tipo que o trabalho seria idêntico ao descrito acima.

2-) Querystring

A “Querystring” é um modelo clássico e talvez o mais utilizado em sistemas Web. A única desvantagem no uso deste recurso é que os valores passados serão visíveis no Navegador e não conseguimos passar objetos. Recomendado para valores pequenos (limite de 255 caracteres) e que não necessitam de segurança. O uso é muito simples, ao redirecionarmos para uma determinada página, adicionamos o primeiro valor usando a seguinte sintaxe: (?Chave=valor). No caso para passarmos mais de um conjunto de valores devemos ir concatenando com o caractere coringa (&). Podemos conferir um exemplo conforme nos ensina na listagem 05.
 
protected void btnEnviarquerystring_Click(object sender, EventArgs e)
{
     string dadosPagina;
dadosPagina = "WebFormQueryString.aspx?nome=" + txtNome.Text +
     "&endereco=" + txtEndereco.Text +
     "&cidade=" + txtCidade.Text +
     "&estado=" + txtEstado.Text +
     "&tipo=" + dropTipo.SelectedItem;
      Response.Redirect(dadosPagina);
}
Listagem 05: Código para enviar valores das Querystring.

No primeiro momento criamos uma variável do tipo “string”, passando a página (WebFormQueryString.aspx) seguido dos pares chave/valor concatenado pelo coringa(&). O método “Response.Redirect” irá nos redirecionar para a segunda página onde iremos carregar estes valores. Listagem 06.

protected void Page_Load(object sender, EventArgs e)
{
   if (!Page.IsPostBack)
   {
     lblNomeRec.Text = Request.QueryString["nome"];
     lblEnderecoRec.Text = Request.QueryString["endereco"];
     lblCidadeRec.Text = Request.QueryString["cidade"];
     lblEstadoRec.Text = Request.QueryString["estado"];
     lblTipoRec.Text = Request.QueryString["tipo"];
   }
}
Listagem 06: Código para receber valores da Querystring.

É recomendável sempre utilizar o evento Page_Load para carregar estes parâmetros. O método “Request.QueryString” identifica a chave e nos retorna o valor inserido. Armazenaremos os resultados em Labels.

3-) Método Server Transfer

Podemos dizer que o método “Server.Transfer”  visivelmente possui o mesmo resultado do conhecido método “Server.Redirect”, nos locomovendo de uma página para outra. A diferença que ao usar o método “Server.Transfer” o servidor conserva os recursos já utilizados, ou seja, ao invés de simplesmente redirecionar para outra página, ele apenas altera o foco no servidor e transfere toda a requisição. Devemos tomar cuidado, pois, o processo de transferência pode operar somente em sites que estão rodando no servidor, lembrando que não podemos utilizar este método para uma página externa ao servidor. Outro detalhe interessante é que o “Server.Transfer” mantém a URL original no Browser.  Para entendermos melhor faremos o uso conforme a listagem 07.

protected void btnEnviarServerTransfer_Click(object sender, EventArgs e)
{
   Server.Transfer("WebFormServerTransfer.aspx", true);
}
Listagem 07: Código para enviar valores via Método “Server.Transfer”.

Nó código acima temos um segundo parâmetro booleano denominado “preserveForm”. Estamos definindo para “True” sendo assim a consulta existente e qualquer variável de formulário ficará disponível para a página para a qual você esta fazendo a transferência. Para recuperarmos faremos conforme a Listagem 08.

protected void Page_Load(object sender, EventArgs e)
{
      if (!Page.IsPostBack)
      {
          var form = Request.Form;
          lblNomeRec.Text = form["txtNome"];
          lblEnderecoRec.Text = form["txtEndereco"];
          lblCidadeRec.Text = form["txtCidade"];
          lblEstadoRec.Text = form["txtEstado"];
          lblTipoRec.Text = form["dropTipo"];
      }
}
Listagem 08: Código para receber valores via Método “Server.Transfer”.

No primeiro ato foi criada uma variável do tipo “var”, recebendo os valores do método “Request.Form”. Ao fazermos esta referência automaticamente conseguimos recuperar qualquer valor do webform anteriormente utilizado. Usaremos os valores dos Textboxes e do DropDownlist.

4-) Classe HttpContext

Através desta classe podemos obter outras classes para manipulações de objetos. Ela encapsula todas as informações específicas sobre uma requisição HTTP, o objeto “HTTPContext” fornece acesso aos objetos em questão. É importante lembrar que os valores armazenados neste objeto serão válidos somente durante a duração de uma requisição. Ver Listagem 09.

protected void btnEnviarHttpContext_Click(object sender, EventArgs e)
{
     HttpContext contexto = HttpContext.Current;
     contexto.Items["nome"] = txtNome.Text;
     contexto.Items["endereco"] = txtEndereco.Text;
     contexto.Items["cidade"] = txtCidade.Text;
     contexto.Items["estado"] = txtEstado.Text;
     contexto.Items["tipo"] = dropTipo.SelectedItem;
     Server.Transfer("WebFormHttpContext.aspx");
}
Listagem 09: Código para enviar valores via classe “HTTPContext”.

Primeiramente instancie o objeto “HTTPContext” atribuindo o contexto corrente da aplicação. Podemos atribuir quais valores desejarmos utilizando o método “Items”. Utilizamos o mesmo comando abordado anteriormente, o Server.Transfer, sendo que desta vez passamos por parâmetro apenas alguns valores. Para receber estes dados faremos o contrário, usando a mesma lógica de raciocínio. Ver Listagem 10.

protected void Page_Load(object sender, EventArgs e)
{
   if (!Page.IsPostBack)
   {
     HttpContext contexto = HttpContext.Current;
     lblNomeRec.Text = contexto.Items["nome"].ToString();
lblEnderecoRec.Text =   contexto.Items["endereco"].ToString();
lblCidadeRec.Text = contexto.Items["cidade"].ToString();
lblEstadoRec.Text = contexto.Items["estado"].ToString();
     lblTipoRec.Text = contexto.Items["tipo"].ToString();
    }
}
Listagem 10: Código para enviar valores via classe “HTTPContext”.
Lembrando que ao utilizar esta classe estamos restritos apenas aos objetos definidos dentro do método “Context.Current.Items”.

Uma dica sobre as variáveis de Sessão

Uma ideia para quem armazena muitas informações nas variáveis de sessão seria criar uma classe para esta tarefa. Um exemplo muito claro para isto seria para quem trabalha com dados de usuários, se tornando mais objetiva tanto para armazenar quanto para recuperar os campos envolvidos. Possuímos os mesmos campos descritos acima nesta classe. É necessário implementar os métodos “Get” e “Set”. Para quem não sabe, criar uma classe no Asp.Net é muito simples, basta clicar com o botão direito sobre a solução e escolher a opção “Add/New Item...”. Defina o nome como: “Usuario.cs”. Ver Listagem 11.

public class Usuario
{
    public Usuario()
    {
    }

    private string _NOME;

    public string NOME
    {
        get { return _NOME; }
        set { _NOME = value; }
    }

    private string _ENDERECO;

    public string ENDERECO
    {
        get { return _ENDERECO; }
        set { _ENDERECO = value; }
    }

    private string _CIDADE;

    public string CIDADE
    {
        get { return _CIDADE; }
        set { _CIDADE = value; }
    }

    private string _ESTADO;

    public string ESTADO
    {
        get { return _ESTADO; }
        set { _ESTADO = value; }
    }

    private string _TIPO;

    public string TIPO
    {
        get { return _TIPO; }
        set { _TIPO = value; }
    }
}
Listagem 11: Classe Usuário.

Seguindo a mesma tela criada anteriormente, iremos codificar o botão da seguinte maneira, Ver Listagem 12.

protected void btnEnviarSessionObjeto_Click(object sender, EventArgs e)
{
    Usuario usuario = new Usuario();
    usuario.NOME = txtNome.Text;
    usuario.ENDERECO = txtEndereco.Text;
    usuario.CIDADE = txtCidade.Text;
    usuario.ESTADO = txtEstado.Text;
    usuario.TIPO = dropTipo.SelectedItem.ToString();

    Session.Add("USUARIO", usuario);
    Response.Redirect("~/WebFormSessionObjeto.aspx");
}
Listagem 12: Código para enviar valores via Session.

Instancie a classe “Usuario” e alimente os seus atributos conforme os valores dos componentes. O principal comando é o “Session.Add”, é neste ato que adicionamos o Objeto como variável de sessão. Para efetuar a leitura destes dados faremos um “TypeCast” para a classe “Usuário” para posteriormente irmos recuperando os dados.
Ver Listagem 13.

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
lblNomeRec.Text = ((Usuario)Session["USUARIO"]).NOME.ToString();
lblEnderecoRec.Text = ((Usuario)Session["USUARIO"]).ENDERECO.ToString();
lblCidadeRec.Text = ((Usuario)Session["USUARIO"]).CIDADE.ToString();
lblEstadoRec.Text = ((Usuario)Session["USUARIO"]).ESTADO.ToString();
lblTipoRec.Text = ((Usuario)Session["USUARIO"]).TIPO.ToString();
    }
}
Listagem 13: Código para receber valores via Session.

Conclusões

 Pudemos aprender neste artigo diversas maneiras de resolver o mesmo tipo de problema, trabalhando com Variáveis de Sessão, Querystring, o Método Server.Transfer e a classe HttpContext. Fica a cargo do desenvolvedor escolher a melhor técnica a seguir.
Abraços e até o mês que vem!


Nenhum comentário:

Postar um comentário