Nesse artigo vamos trabalhar com duas tecnologias muito usadas: o XML (eXtensible Markup Language) que é uma linguagem de marcação extensiva definida em modos específicos sugerida pela W3C para criação e uso de documentos; e o JSON (JavaScript Object Notation) que é uma notação de JavaScript escrito de maneira simples para troca e armazenamento de dados.

Ambas as tecnologias JSON e XML podem ser usadas para importar objetos nativos na memória em um formato de troca de dados com base no texto original. Além disso, ambos os formatos de troca de dados são compostos de uma única forma, ou seja, em um determinado formato de texto pode ser gerado um arquivo equivalente ao outro. Entretanto, ao decidir sobre um formato inadequado para troca de dados, não é tão simples como escolher um e rejeitar o outro, ou escolher ambos em determinados casos, mas deve determinar qual formato tem as características que o tornam e combinam melhor escolha para uma determinada aplicação. Por exemplo, o XML tem seus ancestrais vindos dos documentos de texto rotulados e tende a se destacar muito bem em que seu adjacente denominado XHTML. Mas, por outro lado, tem as suas raízes em JSON e seus tipos e estruturas de linguagens de programação fornece, portanto, a atribuição de forma natural e diretamente disponível para a troca de dados estruturados.

Já o AJAX (Asynchronous JavaScript and XML) é um modelo assíncrono da união entre JavaScript e XML para uso em tecnologias web que fazem comunicação com o usuário de forma interativa. Em aplicações web clássicas, uma página web é um documento HTML que pode ser processado por um navegador para informações a serem mostrados para o usuário, tendo certas limitações. Por isso o AJAX veio com o intuito de permitir que a página seja muito mais eficiente e comunicativa. Este código é executado em segundo plano agindo como o "cérebro" enquanto o documento HTML é apresentado na janela do navegador. O código pode detectar eventos como chaves de cursor ou cliques do mouse, e executar ações que respondem a estes eventos, sem fazer um retorno de volta para o servidor. Através do Ajax, uma página web se sente como um aplicativo de sistema operacional, pois ela responde rapidamente, quase imediatamente às ações do usuário, sem atualização de página inteira. Essa tecnologia pode promover continuamente a atualização com a página com a forma assíncrona buscando dados do servidor armazenado em qualquer origem, como que se tornasse em aplicações próprias executadas em desktops.

Em aplicações web tradicionais, ao executar um clique é preciso esperar a atualização da página porque a Web foi originalmente projetada para documentos de navegação HTML, onde um navegador da web responde às ações do usuário, rejeitando a página HTML atual e enviando uma solicitação HTTP que volta para o servidor web. Depois de realizar algum processamento, o servidor retorna uma nova página HTML para o navegador, que exibe a nova página. O ciclo de solicitações do navegador, onde o servidor responde é denominado “síncrono”, o que significa que acontece em tempo real, fazendo com que o usuário deva esperar e não possa realizar outras tarefas. Em aplicações baseadas em AJAX, as atualizações de tela parciais substituem a espera do HTML que é vinda de uma atualização decorrente do clique e a sua comunicação assíncrona substitui a atual solicitação ou resposta. Este modelo desacopla a interação do usuário a partir da interação do servidor, ao atualizar somente aqueles elementos de interface que contém novas informações para os usuários. Esta aplicação torna a arquitetura mais eficiente, eliminando a espera e fazendo com que os usuários possam continuar trabalhando. Da mesma forma, reduz o consumo de largura de banda da rede e carga do servidor para melhor desempenho da aplicação.

Nesse artigo será utilizado um exemplo clássico de Consulta de Alunos, que consistirá em uma página ASP.NET bem simples e sua pesquisa retornará seu ID, nome, o RA, sua nota e sua nota final arredondada de acordo com o arquivo XML criado.

Começando o Projeto

Para esse exemplo será usado o ambiente de desenvolvimento Microsoft Visual Studio 2010. Com isso, será criado um novo projeto ASP .NET, conforme demonstra a Figura 1.

Tela de configuração para uma nova aplicação ASP .NET.
Figura 1. Tela de configuração para uma nova aplicação ASP .NET. É preciso definir um Name (nome para o projeto), Location (localização) e se estiver do jeito que está na figura, pode dar OK
Nota: Nesse exemplo foi definida a utilização da plataforma .NET Framework 4.

Agora, para dar continuidade ao projeto serão criados novos arquivos os quais serão responsáveis por fazerem interligações, trazendo informações de um arquivo, manipulando seus registros e imprimindo num formato do tipo HTML a ser visualizado num navegador web. A seguir serão criados arquivos nos formatos .aspx e .xml, porém, a pasta Properties (propriedades do sistema), References (bibliotecas declaradas) e o arquivo de configuração padrão Web.config não serão abordadas e ficarão no modo padrão. Com isso, basta adicionar New Item para a aplicação tenha os seguintes nomes: notas.xml, ObterJSON.aspx e Default.aspx, de acordo com a Figura 2.

Figura
Figura 2. Hierarquia dos arquivos localizados no Solution Explorer para o projeto Consulta de Alunos

Observação: Outra forma para criação do arquivo em XML pode ser dentro do bloco de notas (notepad) e depois que estiver salvo, basta incluir este arquivo para o projeto, de acordo com a Figura 2.

Configurando o Arquivo XML

Inicialmente, antes de começar a implementação do projeto, será criado informações para serem inseridas dentro do arquivo notas.xml de acordo com a Listagem 1 onde a página web será encarregada de fazer as pesquisas e retornar os dados.


<?xml version="1.0" standalone="yes"?>
<DocumentElement>
  <notas>
    <usu_id>17165</usu_id>
    <alu_ra>3391305126</alu_ra>
    <usu_nome>TESTE A1</usu_nome>
    <nota_final>8,42</nota_final>
    <nota_final_arredondada>8,5</nota_final_arredondada>
  </notas>
  <notas>
    <usu_id>17176</usu_id>
    <alu_ra>3391305266</alu_ra>
    <usu_nome>TESTE B2</usu_nome>
    <nota_final>9,26</nota_final>
    <nota_final_arredondada>9,5</nota_final_arredondada>
  </notas>
  <notas>
    <usu_id>19081</usu_id>
    <alu_ra>3391305312</alu_ra>
    <usu_nome>TESTE C3</usu_nome>
    <nota_final>8,08</nota_final>
    <nota_final_arredondada>8,0</nota_final_arredondada>
  </notas>
  <notas>
    <usu_id>19505</usu_id>
    <alu_ra>3391305339</alu_ra>
    <usu_nome>TESTE D4</usu_nome>
    <nota_final>6,15</nota_final>
    <nota_final_arredondada>6,0</nota_final_arredondada>
  </notas>
  <notas>
    <usu_id>17177</usu_id>
    <alu_ra>3391305215</alu_ra>
    <usu_nome>TESTE E5</usu_nome>
    <nota_final>2,76</nota_final>
    <nota_final_arredondada>3,0</nota_final_arredondada>
  </notas>
  <notas>
    <usu_id>17164</usu_id>
    <alu_ra>3391305231</alu_ra>
    <usu_nome>TESTE F6</usu_nome>
    <nota_final>3,89</nota_final>
    <nota_final_arredondada>4,0</nota_final_arredondada>
  </notas>
</DocumentElement>
Listagem 1. Exemplo de uma lista de dados a serem armazenados em cada linha no arquivo

Neste caso, o arquivo notas.xml necessita que todas as suas informações estejam sendo declaradas entre tags para que algum mecanismo interpretador possa entender o que está dentro, a começar pela descrição do documento (localizada no topo), a descrição de cada registro armazenado nas tags e no seu interior as tags complementares que se referem ao id do aluno, RA, nome, nota final e a nota final arredondada. Todo o final desse formato de arquivo precisa de uma tag finalizadora denominada .

Programando a Funcionalidade do Projeto

Após ter complementado o arquivo de XML com todos os dados dentro do arquivo ObterJSON.aspx, será implementado o seguinte código descrito na Listagem 2.


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

<%@ Import Namespace="System.Data" %>
<%
  
  System.Threading.Thread.Sleep(500);
  
  if (Request.QueryString["RecuperarAlunos"] != null)
  {
      string termo = Request.Form["termo"];

      DataTable dt = new DataTable();

      dt.Columns.Add("usu_id");        
      dt.Columns.Add("alu_ra");
      dt.Columns.Add("usu_nome");
      dt.Columns.Add("nota_final");
      dt.Columns.Add("nota_final_arredondada");

      dt.TableName = "notas";
      dt.ReadXml(HttpContext.Current.Server.MapPath("~/notas.xml"));

      ArrayList vet = new ArrayList();
      int i = 0;
      foreach (DataRow row in dt.Rows)
      {
          bool adiciona = false;
          if (termo == null)
              adiciona = true;
          else if (row["usu_nome"].ToString().ToUpper().Contains(termo.ToUpper()))
              adiciona = true;

          
          i++;
          if (adiciona)
          {

              vet.Add("{\"id\" : \"" + row["usu_id"].ToString() +
                    "\", \"nome\" : \"" + row["usu_nome"].ToString() +
                     "\", \"ra\" : \"" + row["alu_ra"].ToString() +
                      "\", \"notaf\" : \"" + row["nota_final"].ToString() +
                       "\", \"nota\" : \"" + row["nota_final_arredondada"].ToString() + "\"}");
          }
      }

      string json = @"[" + string.Join(",", vet.ToArray()) + "]";



      Response.Clear();
      Response.ContentType = "application/json";
      Response.Write(json);
      Response.End();


  }
%>
Listagem 2. Código inserido no arquivo ObterJSON.aspx

Por padrão, ao criar uma página web ASP .NET, a mesma vem com a tag Page Language="C#" no topo superior para especificar a linguagem a ser utilizada na página do servidor, que neste caso é o C#.

Toda página que aparecer com o delimitador <% %> indica que o conteúdo que estiver dentro será interpretado pelo servidor.

Antes, é inserido o código <%@ Import Namespace="System.Data" %> que é uma importação da biblioteca padrão para manipulação de dados.

A linha System.Threading.Thread.Sleep(500); é uma definição ao tempo de demora para o carregamento dos dados na tela que estão em memória.

Dentro da condição if (Request.QueryString["RecuperarAlunos"] != null) verifica-se se o método recebido é diferente de nulo: se sim é porque ocorreu o evento e é executado o que estiver dentro dessa condição.

A linha string termo = Request.Form["termo"]; significa que uma string declarada recebe a variável de recebimento “termo” vindo por requisição de formulário.

A linha DataTable dt = new DataTable(); indica que uma nova instância para o DataTable é criada.

O comando dt.Columns.Add("usu_id"); faz uma adição ao DataTable referente a coluna do ID do aluno.

O comando dt.Columns.Add("alu_ra"); faz uma adição ao DataTable referente a coluna do RA do aluno.

O comando dt.Columns.Add("usu_nome"); adiciona ao DataTable o nome do aluno.

O comando: dt.Columns.Add("nota_final"); faz uma adição ao DataTable referente a coluna da nota final do aluno.

O comando dt.Columns.Add("nota_final_arredondada"); adiciona ao DataTable a nota final arredondada do aluno.

O comando: dt.TableName = "notas"; define um nome para o DataTable, e o comando dt.ReadXml(HttpContext.Current.Server.MapPath("~/notas.xml")); aponta para o caminho do arquivo notas.xml (localizados na mesma pasta) e automaticamente faz a leitura, adicionando os dados para o DataTable.

A linha ArrayList vet = new ArrayList(); é uma declaração para o ArrayList (coleção de vetores num Array).

Em seguida é criada uma variável contador e com o comando: foreach (DataRow row in dt.Rows) o laço de repetição percorre todos os dados do DataTable.

Dentro desse foreach foi criado a variável “adiciona” (do tipo booleano) que inicialmente recebe valor falso: se a string “termo” vier nula então essa variável torna-se verdadeira, independente de ter outros valores armazenados.

A condição else if (row["usu_nome"].ToString().ToUpper().Contains(termo.ToUpper())) significa que se tiver apenas a coluna do nome em memória, a variável “adiciona” também se torna verdadeira. Na linha seguinte contém um contador para ir incrementando os registros.

Agora se a variável “adiciona” existir, é acrescentado dentro de um vetor o ID, nome, o RA, a nota final e a nota final arredondada do aluno.

O comando string json = @"["+ string.Join(",", vet.ToArray()) + "]"; significa que a “String json” está recebendo os dados do vetor coletado anteriormente para ser armazenado posteriormente.

O comando Response.Clear(); é responsável por limpar o índice atual do Response.

O comando Response.ContentType = "application/json"; é responsável por indexar o tipo de cadeia de conexão a ser atribuída depois com os valores, que no caso é do tipo json.

O comando Response.Write(json); é responsável por “escrever” a cadeia de caractere recebida pela variável json anteriormente.

E por fim, o comando Response.End(); é responsável por encerrar a transição liberando os dados da memória.

Definindo a Página de Exibição ao Usuário

Agora será necessário definir um padrão de exibição dos dados armazenados para que sejam manipulados e exibidos para o usuário. Use o código descrito na Listagem 3 para implementar dentro do arquivo Default.aspx criado anteriormente.


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" 
Inherits="_Default" %>
 
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script>
 
        document.addEventListener("DOMContentLoaded", function () {
            pesquisa.inicializar();
        }, false);
 
 
        var pesquisa = {
 
            inicializar: function () {
 
                document.getElementById("btnRecuperarAlunos").addEventListener("click", 
                function () {
                    pesquisa.recuperarAlunos();
                }, false)
 
            },
 
            recuperarAlunos: function () {
 
                var ulResultado = document.getElementById("ulResultado");
                ulResultado.innerHTML = "<li>carregando...</li>";
 
                var id = document.getElementById("tbAluno").value;
                var nome = document.getElementById("tbAluno").value;
                var ra = document.getElementById("tbAluno").value;
                var notaf = document.getElementById("tbAluno").value;
                var nota = document.getElementById("tbAluno").value;
                var request = new XMLHttpRequest();
 
                var url = "ObterJson.aspx?RecuperarAlunos=true";
                request.open("POST", url, true);
                request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
 
                request.onreadystatechange = function () {
 
                    if (request.status == "200" &&
                        request.readyState == 4) {
                        var vetor = JSON.parse(request.responseText);
                        ulResultado.innerHTML = ""
                        for (var i = 0; i < vetor.length; i++) {
 
                            var li = document.createElement("li");
                            li.innerHTML = " ID do aluno: " + vetor[i].id + "<br /> 
                            Nome do aluno: " + vetor[i].nome + "<br /> RA: " 
                            + vetor[i].ra + "<br /> Nota: "+ vetor[i].notaf + 
                            "<br /> Nota Final: " + vetor[i].nota + "<br/><br/>";
                            ulResultado.appendChild(li);
                        }
                    }
                };
 
                var enviar = "termo=" + nome;
                request.send(enviar);
            },
 
        }
 
    </script>
</head>
<body>
    <div>
        <input type="text" id="tbAluno" placeholder="nome do aluno" />
        <input type="button" id="btnRecuperarAlunos" value="Recuperar Alunos" />
        <ul id="ulResultado">
            
        </ul>
    </div>
</body>
</html>
Listagem 3. Código inserido no arquivo: Default.aspx

Como no arquivo anterior ObterJSON.aspx, neste também tem a tag Page Language="C#" localizada no topo superior especifica a linguagem a ser utilizada na página do servidor, que neste caso é o C#.

Dentro da tag é criado uma condição para verificar se a página está criada conforme a árvore de domínio (DOM). Se estiver criada, o “pesquisar” é inicializado. Por padrão é false. Se estiver inicializado, o “pesquisar” receberá o ouvinte que efetuará a ação do objeto carregado na tela, que no caso, verifica se o usuário clicou no botão: btnRecuperarAlunos. O comando: pesquisa.recuperarAlunos(); envia para a pesquisa iniciada anteriormente, o método: recuperarAlunos() que será iniciado.

A função recuperarAlunos() é responsável por exibir em uma lista a concatenação contendo seus valores. Antes, são criadas variáveis para serem armazenadas os dados, uma variável para inicializar o XMLHttpRequest referente ao status do Ajax e também uma url é passada por parâmetro onde ela é receberá os dados vindo do arquivo ObterJSON.aspx.

O comando: request.open("POST", url, true); é responsável por “abrir” uma nova requisição via POST passando a url criada por parâmetro e o comando: request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); é o padrão de como o Ajax vai atuar desde o início ao fim da requisição.

A função request.onreadystatechange é executada quando o servidor houver retorno e verifica o atual status da requisição e se não ocorrer algum erro, é executado o JSON para trazer os resultados obtidos em um vetor concatenando em uma lista via HTML.

É criado a variável: var enviar = "termo=" + nome; que é destinado para concatenar o objeto de pesquisa ao “termo” e o comando: request.send(enviar); é responsável por enviar via requisição a variável concatenada (ou não) com valores.

E finalmente, dentro das tags: é declarado um input type="text" para que o usuário digite sua consulta do nome, um input type="button" para recuperar o aluno pesquisado. Caso o usuário não informe valor, é feita a busca e retornado todos os registros do arquivo e abaixo é declarada a lista: <ul> onde o resultado será mostrado em forma de itens dentro dessa área com preenchimento pelo Ajax.

Exibindo a Página Web

Pronto, agora é só executar o projeto ASP .NET. Basta apertar Ctrl+F5 ou seguir os passos conforme ilustra a Figura 3.

Figura 3
Figura 3. Caminho para visualizar a página ASP .NET criada. É necessário clicar com o botão direito em Default.aspx e clicar em View in Browser
Nota: É recomendado acessar a página que tenha suporte ao HTML 5.

Após ter executado, os itens da página ficará de acordo com a Figura 4.

Figura 4
Figura 4. Parte da tela da página ASP .NET sendo executado no navegador Mozilla Firefox

Para utilizar o sistema, basta clicar no botão: “Recuperar Alunos” que retornará todos os alunos e seus respectivos dados. Agora se desejar fazer uma pesquisa, basta digitar uma parte dos caracteres no input text: “nome do aluno” e depois clicar no botão: “Recuperar Alunos” que logo retornará os dados conforme ilustra a Figura 5.

Figura 5
Figura 5. Consulta realizada com êxito. Foi digitado o aluno com o nome de Teste A1 e clicado no botão Recuperar Alunos, logo os dados relativos a ID, nome, RA, nota e nota final arredondada são carregados