O desenvolvimento de aplicações Web com o Delphi está finalmente consolidado, depois de tantas idas e vindas. A tecnologia que usamos hoje é Delphi Prism, Visual Studio 2008, ASP.NET 3.5 + ASP.NET AJAX, e futuramente, Delphi Prism, Visual Studio 2010, ASP.NET AJAX 4.0, ADO.NET Data Services e ADO.NET Entity Framework.
O banco de dados utilizado pela maioria dos desenvolvedores Delphi é, sem dúvida, o Firebird, apesar do SQL Server ser o banco mais indicado para trabalhar com o ASP.NET. Então, já que estamos na coluna QuickUpdate, que tal uma atualização bem rápida, tipo uma reciclagem em 10 min., uma aplicação de cadastro de usuários que utilize as tecnologias disponíveis atualmente no Prism? Vamos lá.
Antes de começar, é importante saber o que faremos: uma aplicação Web multicamadas, onde o browser enviará as informações digitadas de um cadastro de usuários (Nome e Email) via AJAX, ou seja, uma chamada assíncrona XML-HTTP sem postbacks e sem refreshs de página. Essas informações serão recebidas por um Web Service, que repassará os dados para uma camada a parte de acesso ao Firebird (chamada DAL), que usa ADO.NET e o provider nativo do Firebird para enviar dados a uma Stored Procedure.
Criando o banco de dados
Primeiro, crie no Firebird um banco de dados chamado USUARIOS.FDB e dentro dele uma tabela com a estrutura da Figura 1. Como você pode ver, é uma tabela extremamente simples. Nosso foco aqui não é o cadastro em si, mas as tecnologias envolvidas. Estou usando o IBExpert para criar o BD, logo, usei a opção AutoInc para o ID usando Sequence/Generator e Trigger. Criei também uma Stored Procedure para inserir os dados nessa tabela, como mostra a Listagem 1.
Figura 1. Tabela de usuários
Listagem 1. Stored Procedure para inserir dados na tabela
create procedure InsertUsuario (
NOME varchar(50),
EMAIL varchar(50))
as
begin
insert into USUARIOS(NOME,EMAIL)
values (:NOME,:EMAIL);
end;
Criando o Web Site
No Prism, inicie um novo ASP.NET Web Site, escolhendo a linguagem Oxygene. No formulário principal, bem no topo, coloque um ScriptManager da aba AJAX Extensions. Esse componente será responsável por gerenciar as chamadas assíncronas feitas à pagina. No form principal, coloque dois TextBox’s (digite “Nome” e “Email” acima deles) e um Input Button (HTML). Seu formulário deve estar semelhante ao mostrado na Figura 2.
Figura 2. Formulário principal da aplicação
Implementando o acesso a dados
Agora precisamos implementar o acesso a dados, nesse caso, vamos trabalhar apenas com a operação de inserção. Para acesso ao Firebird a partir do ASP.NET, vamos usar o que há de melhor, o driver do próprio Firebird para ADO.NET. Então baixe e instale-o a partir do endereço http://www.firebirdsql.org/index.php?op=files&id=netprovider (versão para .NET 3.5). Jamais use um SqlDataSource ou dbxDataSource em aplicações reais.
No ASP.NET vamos implementar nossa classe de acesso a dados, chamada DAL (Data Access Layer). Clique de direita no nome do Web Site no Solution Explorer e escolha Add>New Item>Class, dando o nome de DAL para ela (coloque na App_Code quando questionado). O código é mostrado na Listagem 2. Para poder usar os objetos do provider ADO.NET de acesso ao Firebird, clique de direita novamente na Solution e localize (browse) o arquivo FirebirdSql.Data.FirebirdClient.dll, por padrão em c:\Program Files\FirebirdClient. Aqui basicamente usamos ADO.NET e seus objetos para enviar os dados ao BD. FbConnection faz a conexão, enquanto o FbCommand executa a instrução através do seu método ExecuteNonQuery. Tudo com parâmetros, para evitar ataques de SQL Injection.
Listagem 2. Classe de acesso ao Firebird usando o provider ADO.NET
namespace;
interface
uses
System,
FirebirdSql.Data.FirebirdClient;
type
DAL = public class
public
method Insert(Nome, Email: String);
// aqui iriam os demais métodos, para update, select etc
end;
implementation
method DAL.Insert(Nome, Email: String);
begin
// Coloque na string abaixo o caminho do seu banco
// Quando em produção, coloque a string no Web.Config
var ConStr := "User=SYSDBA;Password=masterkey;Database=C:\FBAJAX\App_Data\Usuarios.fdb;DataSource=localhost;";
var Con := new FbConnection(ConStr);
// caso não queira usar SPs use o comando abaixo
// var SQL := "insert into USUARIOS(Nome,Email) values (@Nome,@Email)";
var SQL := "InsertUsuario";
var Cmd := new FbCommand(SQL,Con);
// Só use a atribuição abaixo quando usar SPs
Cmd.CommandType := System.Data.CommandType.StoredProcedure;
Cmd.Parameters.AddWithValue("@Nome", Nome);
Cmd.Parameters.AddWithValue("@Email", Email);
Con.Open();
try
Cmd.ExecuteNonQuery();
finally
Con.Close();
end;
end;
end.
Criando o Web Service
O próximo passo é criar o Web Service que receberá os dados do browser via AJAX. Para isso, no Solution Explorer dê um clique de direita e escolha Add>New Item>Web Service e implemente-o conforme a Listagem 3. Aqui nada de mais, simplesmente recebemos os parâmetros e repassamos à classe DAL. Poderíamos ter feito o acesso a dados aqui no próprio Web Service, mas separar o ADO.NET em uma camada a parte nos dá mais independência, além de ser uma boa prática.
Listagem 3. Web Service para receber dados do browser
namespace;
interface
uses
System,
System.Web.Services,
System.Web.Services.Protocols;
type
[WebService(&Namespace := 'http://tempuri.org/')]
[WebServiceBinding(ConformsTo := WsiProfiles.BasicProfile1_1)]
// É necessário decorar a classe com o atributo abaixo
// para poder chamar a partir de uma app AJAX
[System.Web.Script.Services.ScriptService]
WebService = public class(System.Web.Services.WebService)
public
method Insert(Nome, Email: String);
end;
implementation
[WebMethod]
method WebService.Insert(Nome, Email: String);
begin
var NewDAL := new DAL();
NewDAL.Insert(Nome,Email);
end;
end.
Chamando o Web Service via JavaScript (AJAX)
No formulário, selecione o ScriptManager e abra o editor da sua propriedade Services. Adicione um novo item, definindo o InlineScript para True e Path para ~/WebService.asmx. Agora, abra o arquivo ASPX e adicione o código da Listagem 4, dentro do elemento Head. Note que esse código vai rodar no navegador, ou seja, é uma chamada assíncrona que não se comunica com a página, não faz postback e gera o mínimo de tráfego necessário. O que fizemos aqui foi adicionar um eventhandler ao botão HTML para chamar o método Insert, que aciona o Web Service e passa os parâmetros. Dois métodos de Callback dão o feedback ao usuário, no caso de sucesso ou falha.
Listagem 4. Código JavaScript usa AJAX para invocar o Web Service
<script type="text/javascript">
function pageLoad()
{
$addHandler( $get("Button1"), "click", Insert );
}
function Insert() {
WebService.Insert(
$get("TextBox1").value,
$get("TextBox2").value,
Sucesso,Erro);
}
function Sucesso() {
alert("Usuário inserido com sucesso");
}
function Erro() {
alert("Erro ao inserir usuário");
}
</script>
Testando
Pronto! Pressione Ctrl+F5 e teste a aplicação no browser (Figura 3).
Algumas dicas importantes caso haja falha na aplicação:
1 - Primeiro teste sua Stored Procedure no banco, via IBExpert;
2 - Depois, teste o Web Service e a classe DAL, dando um clique de direita no arquivo ASMX no Solution Explorer e escolhendo View in Browser;
3 - Finalmente, teste a aplicação no browser, lembrando de setar a default.aspx como página padrão (clique de direita + Set as Start Page). Uma dica final, considere o uso do IE para teste da sua aplicação AJAX, ele possui uma melhor integração para exibição de erros e depuração.
Figura 3. Testando a aplicação AJAX inserindo dados no Firebird
Simples? Sim, com certeza, mas veja que algumas pequenas coisas fazem a diferença:
1 – Usamos Stored Procedures, o que aumenta em muito a performance de aplicações, principalmente em ambiente Web multi-thread;
2 – Desenvolvemos uma aplicação multicamadas, uma excelente prática em ASP.NET. Uma dica interessante seria criar mais uma camada (de negócio, chamada BLL) e objetos DTO para trocas de informações entre camadas (veja meu artigo na edição 98);
3 – Usamos o provider nativo do Firebird para ADO.NET, o que aumenta a performance consideravelmente, principalmente se compararmos ao uso de outros providers, como OleDB, ODBC, BDP;
4 – Ao usar o provider nativo do Firebird, por tabela contamos com um Connection Pooling, que basicamente é uma cache de conexões em memória. Ou seja, um Open não necessariamente vai abrir uma conexão, pode pegar uma do pool, o que literalmente faz a aplicação voar;
5 – E finalmente, enviamos a tela para o browser e não trafegamos mais nada além de dados, via chamadas a um Web Service, usando JavaScript e AJAX. Essa é uma tendência forte no desenvolvimento de aplicações Web hoje, focar no desenvolvimento CLIENT.
Futuro?
O Visual Studio 2010 e .NET 4.0 já estão aí em versão beta, o Delphi Prism certamente estará lá quando for lançada a versão final (já existe uma versão beta do Prism para VS2010). O ASP.NET 4.0 vem focado fortemente no desenvolvimento client-side e JavaScript. É isso mesmo, depois de anos e anos acreditando que deveríamos colocar todo o processamento no servidor, seja em uma aplicação client/server, em SPs no BD, no servidor Web, ou no app server em multicamadas, o futuro traça outro rumo. Uma tecnologia chamada ADO.NET Data Services usa o padrão REST que permite acesso aos dados como recursos, e não serviços, através da URL. Isso roda no servidor, com acesso a dados feito com ADO.NET Entity Framework. O browser não se comunica com um Web Form ASP.NET, mas usa AJAX e muito processamento cliente para receber dados em XML ou JSON e exibir ao cliente. Mais? Sim, vamos usar Silverlight para desenvolver aplicações RIA (Rich Internet Applications) com Prism e obter dados do ADO.NET Data Services. Em suma, acabou o vai e vem de telas na Web, enviamos o form (seja ASP.NET, Silverlight, Flash, HTML) uma única vez e a seguir toda a comunicação é assíncrona. Se usar ASP.NET AJAX 4.0, contará com o uso de client-templates, que são basicamente, a grosso modo, uma versão cliente em JavaScript de controles servidores ASP.NET. Tudo em HTML, CSS e JavaScript. E o Delphi 2010 (Win32) não vai ficar de fora não, por exemplo, o DataSnap 2010 também suportará padrões REST e JSON. Está preparado? A ClubeDelphi está. O Prism certamente estará.
Bem-vindos ao futuro. Grande abraço e até a próxima edição.
See Delphi Prism in Visual Studio 2010 Beta 1
http://blogs.remobjects.com/blogs/mh/2009/05/19/p282