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 DiasASP.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