Desenvolvimento - ASP. NET

Passando um dataset do ASP.NET para o Javascript

Vamos ver a diferença entre usar o updatepanel do ajax.net e deixar que o javascript preencha a tela. Veremos também como passar um dataset do asp.net para o javascript.

por Gustavo Dias



ASP.NET e AJAX

O Ajax.net é uma biblioteca fantástica e possui recursos muito interessantes, como por exemplo o updatepanel já que só precisamos colocar dentro dele a parte da página que precisa ser atualizada dinamicamente e ele faz todo o resto automaticamente. Mas quando precisamos desenvolver uma aplicação com grande número de acesso e grande tráfego de dados não seria uma boa pratica de desenvolvimento usar o updatepanel.

Um dos conceitos do Ajax é a de que o browser não seja usado apenas para exibir informações, mas sim que ele seja usado como uma extensão da aplicação. E quando desenvolvemos uma aplicação utilizando o updatepanel do AJAX.NET toda a lógica de negócio fica no servidor, contrariando assim o conceito do Ajax, perdendo desempenho pois ao invés de retornar apenas os dados, o .NET retorna o HTML pronto para exibição e atualiza tudo o que esta dentro do updatepanel. Só que por outro lado não podemos simplesmente passar os dados para o Java script, você não pode simplesmente passar um dataset do .net para o Java script.

Aqui iremos desenvolver uma pequena aplicação que contém uma função que consegue fazer exatamente isso, na verdade iremos transformar o dataset em uma estrutura de dados que pode ser passada para o Java script. E veremos as diferença entre usar o updatepanel e deixar o Java script preencher a página.

Vamos ao trabalho

Para desenvolver este exemplo utilizarei a Microsoft Visual Web Developer 2005 Express Edition com o Ajax control toolkit instalado e um banco de dados ACCESS.

Iremos começar pelo banco de dados crie um banco de dados do ACCESS chamado “teste.mdb” dentro dele devemos criar uma tabela chamada “clientes” com três campos:

codCliente – numeração automática

Nome – texto

Telefone – texto

Insira alguns dados no banco de dados que criamos.

Primeiro crie um novo web site e escolha o template Ajax Control Toolkit Web Site e escolha a linguagem C#.

No HTML abaixo não há nada demais, basicamente ele é composto de um scriptmanager que registra um Java script um detalhe muito importante é o seguinte parâmetro enablepagemethods="true" pois ele é quem habilita a página a chamar os métodos assincronamente, uma div que receberá as informações dos clientes, uma div que é preenchida com a data atual todas as vezes que é feito um postback e de três botões:

btnClientSide – Que preenchera o formulário assincronamente.

btnServerSide – Que chamara uma função no servidor para preencher o formulário através de um updatepanel.

Limpar – Que limpa o formulário.

Abra a pagina Default.aspx e a codifique o HTML da seguinte maneira:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<link href="css/StyleSheet.css" rel="stylesheet" type="text/css" />

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

    <title>Passando Dataset para o javascript</title>

</head>

<body>

    <form id="Form1" runat="server">

        <asp:scriptmanager id="scriptmanager1"

         runat="server" enablepagemethods="true">

         <Scripts>

         <asp:ScriptReference Path="scripts.js" />

         </Scripts>

         </asp:scriptmanager>

         <div class="content">

            <fieldset>

            <legend>Horário do último Postback</legend>

                <div id="dvPost" runat="server">

                </div>

            </fieldset>

            <asp:UpdatePanel runat="server" ID="up1">

            <ContentTemplate>

            <fieldset>

            <br />

                <legend>Clientes cadastrados</legend>

                    <div id="dvResult" runat="server">

                            <span>Click em preencher para baixar os dados.</span>

                    </div>

             </fieldset>

            </ContentTemplate>

          <Triggers>

          <asp:AsyncPostBackTrigger ControlID="btnServerSide" EventName="ServerClick" />

          </Triggers>

            </asp:UpdatePanel>

            <br />

            <br />

            <div class="buttons">

                <input type="button" id="btnClientSide" onclick="preencheTable()" value="Preencher Client Side" />

                <input type="button" id="btnServerSide" runat="server"  value="Preencher Server Side" onserverclick="btnServerSide_ServerClick" />

                <input type="button" id="btnLimpar" onclick="Limpar()" value="Limpar" />

            </div>           

         </div>

    </form>

</body>

</html>

Os comentários sobre o codefile foram colocados diretamente no código.

Agora abra o arquivo Default.aspx.cs e o codifique da seguinte maneira:

using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using System.Web.Services;

using System.Collections.Generic;

using System.Collections;

using System.Data.OleDb;

public partial class _Default : System.Web.UI.Page

{

    /* Preenche a div dvPost com a data atual para demosntrar que a página é atualizada sem postback*/

    protected void Page_Load(object sender, EventArgs e)

    {

        dvPost.InnerHtml = DateTime.Now.ToString();

    }

    /* Método com a tag [WebMethod] que habilita o método a ser       chamado assincronamente este metodo

    lê os dados dos clientes e chama o método serealiza para poder        

mandar os dados para o javascript*/

    [WebMethod]

    public static IDictionary<string, object> getClientes()

    {

        OleDbDataAdapter da = new OleDbDataAdapter("Select * from clientes", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + HttpContext.Current.Server.MapPath("~/teste.mdb;"));

        DataSet ds = new DataSet();

        try

        {

            da.Fill(ds, "clientes");

        }

        catch (Exception e)

        {

            Dictionary<string, object> result = new Dictionary<string, object>();

            result["error"] = e.Message;

        }

        return Serializa(ds);

    }

    /* O principal método de nossa classe pois é ele que transforma o *dataset em uma estrutura de dados que pode ser enviada ao javascript.*/

    private static IDictionary<string, object> Serializa(DataSet obj)

    {

        if (obj != null)

        {

            Dictionary<string, object> result = new Dictionary<string, object>();

            Dictionary<string, object> dicDS = new Dictionary<string, object>();

            Dictionary<string, object> dicDT = new Dictionary<string, object>();

            Dictionary<string, object> dicColum = new Dictionary<string, object>();

            ArrayList ListRow = new ArrayList();

            foreach (DataTable dt in obj.Tables)

            {

                ListRow = new ArrayList();

                foreach (DataRow row in dt.Rows)

                {

                    dicColum = new Dictionary<string, object>();

                    foreach (DataColumn dc in dt.Columns)

                    {

                        dicColum.Add(dc.ColumnName, row[dc]);

                    }

                    ListRow.Add(dicColum);

                }

                dicDT["Rows"] = ListRow;

                dicDS.Add(dt.TableName, dicDT);

            }

            result["Tables"] = dicDS;

/*Note que que estamos inserindo algumas informações a mais *fora os dados em si, como por exemplo o count que que nos *informara quantas tabelas contém o dataset, aqui se *necessário vocês podem colocar outras informações*/

            result["count"] = obj.Tables.Count;

            result["error"] = null;

            return result;

        }

        return new Dictionary<string, object>();

    }

/*Método que é chamado ao click do botão btnServerSide ele le os *dados dos clientes e preenche a div dvResult*/

    protected void btnServerSide_ServerClick(object sender, EventArgs e)

    {

        OleDbDataAdapter da = new OleDbDataAdapter("Select * from Tabela1", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + HttpContext.Current.Server.MapPath("~/teste.mdb;"));

        DataSet ds = new DataSet();

        try

        {

            da.Fill(ds, "Tabela1");

        }

        catch (Exception ex)

        {

        }

        string strAux = string.Empty;

        for (int i = 0; i < ds.Tables[0].Rows.Count; i++)

        {

            strAux = strAux + "<span>Cliente: " + ds.Tables[0].Rows[i]["Nome"].ToString();

            strAux = strAux + " Telefone: " + ds.Tables[0].Rows[i]["Telefone"].ToString();

            strAux = strAux + "<span><br/>";

        }

        dvResult.InnerHtml = strAux;

    }

}

Agora iremos criar o arquivo que tera o javascript assim como o codefile coloquei os comentários diretamente no código, clique no botão Add New Item, escolha a opção JScript file de o nome de scripts.js e codifique igual ao exemplo abaixo:

// scripts.js

/* Função chamada ao clique do botão btnClienteSide ela chama o webmethod getClientes e passa como parametro a função preencheTable_callback que receberá os dados retornados.*/

function preencheTable()

{

    PageMethods.getClientes(preencheTable_callback);

}

/*Apenas limpa a div dvResult para melhor comparar o preenchimento client-side e server-side*/

function Limpar()

{

    document.getElementById("dvResult").innerHTML = "Click em preencher para baixar os dados.";

}

/*Recebe os dados enviados pela função .NET e preenche a div*/

function preencheTable_callback(res)

{

    if (res.error == null)

    {

            var strAux = "";

            var dt = res.Tables.Tabela1;

            for(i=0;i<dt.Rows.length;i++)

            {

                strAux = strAux + "<span>Cliente: " + dt.Rows[i].Nome;

                strAux = strAux + " Telefone: " + dt.Rows[i].Telefone;

                strAux = strAux + "<span><br/>";

            }

            document.getElementById("dvResult").innerHTML = strAux;

    }

}

Agora criaremos um arquivo css apenas para deixar a página mais apresentável, crie uma nova pasta chamada css e crie um arquivo Style Sheet chamado StyleSheet.css e codifique da seguinte maneira:

body {

}

.content

{

         text-align:center;

}

fieldset

{

         border:10;

         border-color:Black;

         width:500px;

         text-align:center;

         font-style:oblique;

}

.buttons

{

         width:500px;

         text-align:center;

}       

Pronto agora que já temos todos os arquivos necessários para a nossa aplicação poderemos debuga-la, e ai tudo certo rodou como esperado?

Agora que já está tudo certo poderemos testar a aplicação, aqui na minha máquina tenho instalado um programa que todos já devem conhecer chamado “httpWatch” com ele poderemos ver, entre outras coisas, a quantidade de dados que estão sendo enviados (send), recebidos(Received) e o tempo que isto leva a cada requisição da aplicação. Rodei minha aplicação, e coloquei o “httpWatch” para registrar os dados trafegados e quando cliquei no botão “Preencher Client Side” e obtive os seguintes resultado, veja na figura1, time 0.159 segundos (circulado de vermelho) foram enviados Send 452 bytes (circulado em azul) e foram recebidos Received 493 bytes(em verde).

Figura 1

Logo em seguida cliquei no botão “Preencher Server Side” o qual vai atualizar tudo que estiver dentro do updatepanel e obtive os seguintes resultados, veja na figura2, time 0.242 segundos (circulado de preto) foram enviados(Send) 1032 bytes circulado em lilás e foram recebidos(Received) 1555 bytes em marrom.

Note que em nenhuma das vezes o horário do ultimo postback foi alterando provando que realmente estamos trabalhando assincronamente.

Figura2

Conclusão

Como vimos é muito mais fácil desenvolver utilizando os componentes do Ajax.net pois apenas arrastamos um updatepanel para a página colocamos os componentes dentro dele e pronto já temos algumas chamadas assíncronas, por outro lado para passar os dados para o Java script temos que não só criar os componentes como também desenvolver o script que ira preencher a tela. Ai fica a dúvida em que situações devo usar o updatepanel e em qual não devo usá-lo. Quando você esta desenvolvendo uma tela simples com um cadastro ou exibição de poucos dados é mais fácil e ágil usar o updatepanel. Agora se você esta desenvolvendo um website robusto com muitas informações que terá um grande número de acessos e uma intensa transferência de dados não aconselho o uso do updatepanel pois como podemos ver ele aumenta muito a quantidade dados transferidos entre o cliente e o servidor e com isso perdemos muita performance podendo até tornar inviável o funcionamento do site.

Espero que esse artigo seja útil e que ajude a internet se tornar cada vez mais útil e criativa.

Até o próximo artigo

Veja mais em http://pt.wikipedia.org/wiki/AJAX_%28programa%C3%A7%C3%A3o%29

Gustavo Dias

Gustavo Dias - Estudante de ciências da computação trabalha com o .NET desde 2006.