O Ajax.net é uma biblioteca fantástica e possui recursos muito interessantes. Como, por exemplo, o updatepanel que só precisamos colocar dentro 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 um grande número de acesso e de tráfego de dados não seria uma boa prática 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 – e 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 JavaScript. Você não pode simplesmente passar um dataset do .net para o JavaScript.
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 JavaScript. E veremos as diferença entre usar o updatepanel e deixar o JavaScript 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 do ACCESS chamado “teste.mdb” e 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 JavaScript um detalhe muito importante, o parâmetro enablepagemethods=”true” pois ele é quem habilita a página para 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 página Default.aspx e 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:[i]updatepanel[/i] 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:[i]updatepanel[/i]>
<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 demonstrar 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 se realiza 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 estamos inserindo algumas informações a mais *fora os dados em si, como por exemplo o count 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 terá 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 parâmetro 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 debugá-la. Tudo 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. 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 último postback foi alterado provando que realmente estamos trabalhando assincronamente.
Figura 2
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 JavaScript, temos que, não só criar os componentes, como também desenvolver o script que irá preencher a tela. Aí fica a dúvida em quais situações devo usar o updatepanel e em qual não devo usá-lo.
Quando você está desenvolvendo uma tela simples com um cadastro ou exibição de poucos dados, é mais fácil e ágil usar o updatepanel. Agora, se você está 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 de 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







