3. Introdução ao desenvolvimento web ASP.NET
3.1. Introduction
O capítulo anterior apresentou os princípios do desenvolvimento web, que são independentes da linguagem de programação utilizada. Atualmente, três tecnologias dominam o mercado de desenvolvimento web:
- J2EE, que é uma plataforma de desenvolvimento Java. Associada à tecnologia Struts, instalada em diversos servidores de aplicativos, a plataforma J2EE é utilizada principalmente em grandes projetos. Devido à linguagem utilizada — Java —, uma aplicação J2EE pode funcionar nos principais sistemas operacionais (Windows, Unix, Linux, Mac OS, ...)
- PHP, que é uma linguagem interpretada e também independente do sistema operacional. Ao contrário do Java, não é uma linguagem orientada a objetos. No entanto, a versão PHP5 deve introduzir a orientação a objetos na linguagem. De fácil acesso, o PHP é amplamente utilizado em projetos de pequeno e médio porte.
- O ASP.NET é uma tecnologia que funciona apenas em máquinas Windows que possuam a plataforma .NET (XP, 2000, 2003, ...). A linguagem de desenvolvimento utilizada pode ser qualquer linguagem compatível com .NET, c.a.d. São mais de uma dezena, a começar pelas linguagens da Microsoft (C#, VB.NET, J#), Delphi da Borland, Perl, Python, ...
O capítulo anterior apresentou breves exemplos para cada uma dessas três tecnologias. Este documento aborda o desenvolvimento web ASP.NET com a linguagem VB.NET. Partimos do princípio de que essa linguagem já é conhecida. Esse ponto é importante. Aqui, nos interessamos exclusivamente por sua utilização no contexto do desenvolvimento web. Vamos explicar melhor esse ponto ao abordar a metodologia MVC de desenvolvimento web.
Uma aplicação web que siga o modelo MVC será arquitetada da seguinte maneira:

Essa arquitetura, chamada de “três camadas” ou “três níveis”, busca seguir o modelo MVC (Model View Controller):
- a interface do usuário é o V (a visualização)
- a lógica de aplicação é o C (o controlador)
- as fontes de dados são o M (Modelo)
A interface do usuário costuma ser um navegador da web, mas também pode ser um aplicativo autônomo que, por meio da rede, enviaria solicitações HTTP ao serviço web e formataria os resultados que este lhe enviasse. A lógica de aplicação é constituída por scripts que processam as solicitações do usuário. A fonte de dados costuma ser um banco de dados, mas também pode ser simples arquivos de texto, um diretório LDAP, um serviço web remoto... É importante que o desenvolvedor mantenha uma grande independência entre essas três entidades, de modo que, se uma delas mudar, as outras duas não precisem mudar, ou apenas minimamente.
- A lógica de negócios da aplicação será colocada em classes separadas da classe que controla o diálogo solicitação-resposta. Assim, o bloco [Logique applicative] acima poderá ser constituído pelos seguintes elementos:

No bloco [Logique Applicative], será possível distinguir
- a classe controladora, que é a porta de entrada do aplicativo,
- o bloco [Classes métier], que reúne as classes necessárias à lógica da aplicação. Elas são independentes do cliente.
- o bloco [Classes d'accès aux données], que reúne as classes necessárias para obter os dados exigidos pelo servlet, geralmente dados persistentes (BD, arquivos, serviço WEB, ...)
- o bloco de páginas ASP, que constitui as visualizações da aplicação.
Em casos simples, a lógica de aplicação costuma se resumir a duas classes:
- a classe controladora, responsável pelo diálogo cliente-servidor: processamento da solicitação, geração das diversas respostas
- a classe de negócios, que recebe do controlador os dados a serem processados e, em troca, fornece-lhe os resultados. Essa classe de negócios, por sua vez, gerencia o acesso aos dados persistentes.
A especificidade do desenvolvimento web reside na criação da classe controladora e das páginas de apresentação. As classes de negócio e de acesso aos dados são classes .NET clássicas, utilizáveis tanto em uma aplicação web quanto em uma aplicação Windows ou mesmo do tipo console. A criação dessas classes requer bons conhecimentos de programação orientada a objetos. Neste documento, elas serão escritas em VB.NET; portanto, partimos do princípio de que essa linguagem é dominada. Nessa perspectiva, não há motivo para nos determos mais do que o necessário no código de acesso aos dados. Em quase todos os livros sobre ASP.NET, há um capítulo dedicado ao ADO.NET. O esquema acima mostra que o acesso aos dados é feito por classes .NET totalmente clássicas, que não sabem que estão sendo utilizadas em um contexto web. O controlador, que é o líder da equipe da aplicação web, não precisa se preocupar com ADO.NET. Ele precisa apenas saber a qual classe deve solicitar os dados de que precisa e como fazê-lo. É só isso. Colocar código ADO.NET no controlador não está de acordo com o conceito MVC explicado acima e não faremos isso.
3.2. As ferramentas
Este documento é destinado a estudantes; portanto, trabalharemos com ferramentas gratuitas que podem ser baixadas da internet:
- a plataforma .NET (compiladores, documentação)
- o ambiente de desenvolvimento WebMatrix, que inclui o servidor web Cassini
- diversos SGBD (MSDE, MySQL)
Recomenda-se ao leitor que consulte o apêndice “Ferramentas da Web”, que indica onde encontrar e como instalar essas diferentes ferramentas. Na maioria das vezes, precisaremos apenas de três ferramentas:
- um editor de texto para escrever as aplicações web.
- uma ferramenta de desenvolvimento VB.NET para escrever o código VB quando for necessário. Esse tipo de ferramenta geralmente oferece auxílio na digitação de código (autocompletamento) e sinalização de erros sintáticos, seja durante a digitação do código, seja durante a compilação.
- um servidor web para testar as aplicações web criadas. Neste documento, utilizaremos o Cassini. O leitor que dispuser do servidor IIS poderá substituir o Cassini pelo IIS. Ambos são compatíveis com .NET. O Cassini, no entanto, está limitado a responder apenas a solicitações locais (localhost), enquanto o IIS pode responder a solicitações de máquinas externas.
Um excelente ambiente comercial para desenvolver em VB.NET é o Visual Studio.NET da Microsoft. Este IDE, com recursos muito abrangentes, permite gerenciar todos os tipos de documentos (código VB.NET, documentos HTML, XML, folhas de estilo, etc.). Para a escrita de código, ele oferece a valiosa ajuda do “preenchimento” automático de código. Dito isso, essa ferramenta, que melhora significativamente a produtividade do desenvolvedor, tem a desvantagem de suas próprias qualidades: ela limita o desenvolvedor a um modo de desenvolvimento padrão que, embora eficaz, nem sempre é adequado.
É possível utilizar o servidor Cassini fora do [WebMatrix], e é isso que faremos com frequência. O executável do servidor está localizado em <WebMatrix>\<versão>\WebServer.exe, onde <WebMatrix> é o diretório de instalação do [WebMatrix] e <versão> é o número da versão:

Abramos uma janela do DOS e acessemos a pasta do servidor Cassini:
E:\Program Files\Microsoft ASP.NET Web Matrix\v0.6.812>dir
...
29/05/2003 11:00 53 248 WebServer.exe
...
Vamos executar o [WebServer.exe] sem parâmetros:

O painel acima nos indica que o aplicativo [WebServer/Cassini] aceita três parâmetros:
- /port: número da porta do serviço web. Pode ser qualquer um. Por padrão, o valor é 80
- /path: caminho físico de uma pasta no disco
- /vpath: pasta virtual associada à pasta física anterior.
Colocaremos nossos exemplos em uma árvore de arquivos cuja raiz é P, com pastas chap1, chap2, ... para os diferentes capítulos deste documento. Associaremos a essa pasta física P o caminho virtual V. Assim, iniciaremos o Cassini com o seguinte comando do DOS:
Por exemplo, se quisermos que a raiz física do servidor seja a pasta [D:\data\devel\aspnet\poly] e sua raiz virtual [aspnet], o comando DOS para iniciar o servidor web será:
É possível colocar esse comando em um atalho. Depois de iniciado, o Cassini instala um ícone na barra de tarefas. Ao clicar duas vezes nele, você tem acesso a um painel para ligar/desligar o servidor:

O painel exibe os três parâmetros com os quais foi iniciado. Ele oferece dois botões de ligar/desligar, bem como um link de teste para a raiz de sua árvore de diretórios da web. Nós clicamos nesse link. Um navegador é aberto e a página URL [http://localhost/aspnet] é solicitada. Obtemos o conteúdo da pasta indicada no campo [Physical Path] acima:

No exemplo, a solicitação URL corresponde a uma pasta e não a um documento da web; portanto, o servidor exibiu o conteúdo dessa pasta e não um documento específico da web. Se nessa pasta houver um arquivo chamado [default.aspx], ele será exibido. Vamos criar, por exemplo, o seguinte arquivo e colocá-lo na raiz da árvore de diretórios da web do Cassini (d:\data\devel\aspnet\poly, neste caso):
Vamos agora acessar o URL [http://localhost/aspnet] usando um navegador:

Vemos que, na verdade, foram exibidos os arquivos URL e [http://localhost/aspnet/default.aspx]. No restante deste documento, indicaremos como o Cassini deve ser configurado por meio da notação Cassini(path,vpath), em que [path] é o nome da pasta raiz da árvore de diretórios da web do servidor e [vpath] é o caminho virtual associado. Vale lembrar que, no servidor Cassini(path,vpath), a URL [http://localhost/vpath/XX] corresponde ao caminho físico [path\XX]. Colocaremos todos os nossos documentos em uma raiz física que chamaremos de <webroot>. Assim, poderemos nos referir ao arquivo <webroot>\chap2\here1.aspx. Para cada leitor, essa raiz <webroot> será uma pasta em seu computador pessoal. Aqui, as capturas de tela mostrarão que essa pasta costuma ser [d:\data\devel\aspnet\poly]. No entanto, isso nem sempre será o caso, pois os testes foram realizados em computadores diferentes.
3.3. Primeiros exemplos
Apresentaremos exemplos simples de páginas da web dinâmicas criadas com o VB.NET. O leitor é convidado a testá-los para verificar se seu ambiente de desenvolvimento está instalado corretamente. Descobriremos que há várias maneiras de construir uma página ASP.NET. Escolheremos uma delas para o restante de nossos desenvolvimentos.
3.3.1. Exemplo básico – variante 1
Ferramentas necessárias: um editor de texto, o servidor web Cassini
Retomamos o exemplo do capítulo anterior. Criamos o seguinte arquivo [heure1.aspx]:
<html>
<head>
<title>Demo asp.net </title>
</head>
<body>
Il est <% =Date.Now.ToString("T") %>
</body>
</html>
Este código é o código HTML com uma tag especial <% ... %>. Dentro dessa tag, é possível inserir código VB.NET. Aqui, o código
gera uma sequência de caracteres C que representa a hora atual. A tag <% ... %> é então substituída por essa sequência de caracteres C. Assim, se C for a sequência 18:11:01, a linha HTML que contém o código VB.NET passa a ser:
Vamos colocar o código anterior no arquivo [<webroot>\chap2\heure1.aspx]. Iniciemos o Cassini (<webroot>,/aspnet) e acessemos, por meio de um navegador, o URL [http://localhost/aspnet/chap2/heure1.aspx]:

Ao obter esse resultado, sabemos que o ambiente de desenvolvimento está instalado corretamente. A página [heure1.aspx] foi compilada, pois contém código VB.NET. Sua compilação gerou um arquivo DLL que foi armazenado em uma pasta do sistema e, em seguida, executado pelo servidor Cassini.
3.3.2. Exemplo básico – variante 2
Ferramentas necessárias: um editor de texto, o servidor web Cassini
O documento [heure1.aspx] mistura código HTML e código VB.NET. Em um exemplo tão simples, isso não representa problema. Se for necessário incluir mais código VB.NET, convém separar ainda mais o código HTML do código VB. Isso pode ser feito agrupando o código VB dentro de uma tag <script>:
<script runat="server">
' cálculo dos dados a serem exibidos pelo código HTML
...
</script>
<html>
....
' exibição dos valores calculados pela parte de script
</html>
O exemplo [heure2.aspx] ilustra esse método:
<script runat="server">
Dim maintenant as String=Date.Now.ToString("T")
</script>
<html>
<head>
<title>Demo asp.net </title>
</head>
<body>
Il est
<% =maintenant %>
</body>
</html>
Colocamos o documento [heure2.aspx] na árvore de diretórios [<webroot>\chap2\heure2.aspx] do servidor web Cassini (<webroot>,/aspnet) e acessamos o documento com um navegador:

3.3.3. Exemplo básico – variante 3
Ferramentas necessárias: um editor de texto, o servidor web Cassini
Aprofundamos o processo de separação do código VB e do código HTML, colocando-os em dois arquivos distintos. O código HTML estará no documento [heure3.aspx] e o código VB no [heure3.aspx.vb]. O conteúdo do [heure3.aspx] será o seguinte:
<%@ Page Language="vb" src="heure3.aspx.vb" Inherits="heure3" %>
<html>
<head>
<title>Demo asp.net</title>
</head>
<body>
Il est
<% =maintenant %>
</body>
</html>
Existem duas diferenças fundamentais:
- a diretiva [Page] com atributos ainda desconhecidos
- o uso da variável [maintenant] no código HTML, embora ela não tenha sido inicializada em nenhum lugar
A diretiva [Page] serve aqui para indicar que o código VB, que irá inicializar a página, está em outro arquivo. É o atributo [src] que indica esse arquivo. Veremos que o código VB pertence a uma classe chamada [heure3]. De forma transparente para o desenvolvedor, um arquivo .aspx é transformado em uma classe derivada de uma classe base chamada [Page]. Nesse caso, nosso documento HTML deve derivar da classe que define e calcula os dados que ele deve exibir. Aqui, trata-se da classe [heure3], definida no arquivo [heure3.aspx.vb]. Além disso, é necessário indicar essa relação pai-filho entre os documentos VB e [heure3.aspx.vb] e os documentos HTML e [heure3.aspx]. É o atributo [inherits] que especifica essa relação. Ele deve indicar o nome da classe definida no arquivo apontado pelo atributo [src].
Vamos agora analisar o código VB da página:
Public Class heure3
Inherits System.Web.UI.Page
' dados da página da web a serem exibidos
Protected maintenant As String
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
': cálculo dos dados da página da web
maintenant = Date.Now.ToString("T")
End Sub
End Class
Observe os seguintes pontos:
- o código VB define uma classe [heure3] derivada da classe [System.Web.UI.Page]. Isso sempre ocorre, pois uma página da web deve sempre derivar de [System.Web.UI.Page].
- a classe declara um atributo protegido (protected) [maintenant]. Sabe-se que um atributo protegido é acessível diretamente nas classes derivadas. É isso que permite que o documento HTML e [heure3.aspx] tenham acesso ao valor do dado [maintenant] em seu código.
- A inicialização do atributo [maintenant] é feita em um procedimento [Page_Load]. Veremos posteriormente que um objeto do tipo [Page] é notificado pelo servidor web sobre uma série de eventos. O evento [Load] ocorre quando o objeto [Page] e seus componentes são criados. O manipulador desse evento é designado pela diretiva [Handles MyBase.Load]
- o nome [XX] do gerenciador do evento pode ser qualquer um. Sua assinatura, porém, deve ser a indicada acima. Não explicaremos isso por enquanto.
- Costuma-se usar o gerenciador de eventos [Page.Load] para calcular os valores dos dados dinâmicos que a página da web deve exibir.
Os documentos [heure3.spx] e [heure3.aspx.vb] são colocados no [<webroot>\chap2]. Em seguida, por meio de um navegador, solicita-se o URL e o [http://localhost/aspnet/chap2/heure3.aspx] ao servidor web (<webroot>,/aspnet):

3.3.4. Exemplo básico – variante 4
Ferramentas necessárias: um editor de texto, o servidor web Cassini
Mantemos o mesmo exemplo de antes, mas agrupamos novamente todo o código em um único arquivo [heure4.aspx]:
<script runat="server">
' dados da página da web a serem exibidos
Private maintenant As String
' evt page_load
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
': calcula-se os dados da página da web
maintenant = Date.Now.ToString("T")
End Sub
</script>
<html>
<head>
<title>Demo asp.net</title>
</head>
<body>
Il est
<% =maintenant %>
</body>
</html>
Encontramos a sequência do exemplo 2:
Desta vez, o código VB foi estruturado em procedimentos. Encontramos aqui o procedimento [Page_Load] do exemplo anterior. Queremos mostrar aqui que uma página .aspx isolada (não vinculada a um código VB em um arquivo separado) é transformada implicitamente em uma classe derivada de [Page]. Assim, é possível utilizar os atributos, métodos e eventos dessa classe. É isso que é feito aqui, onde utilizamos o evento [Load] dessa classe.
O método de teste é idêntico aos anteriores:

3.3.5. Exemplo básico – variante 5
Ferramentas necessárias: um editor de texto, o servidor web Cassini
Assim como no exemplo 3, separamos o código VB e o código HTML em dois arquivos distintos. O código VB é colocado no arquivo [heure5.aspx.vb]:
Public Class heure5
Inherits System.Web.UI.Page
' dados da página da web a serem exibidos
Protected maintenant As String
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
': calcula-se os dados da página da web
maintenant = Date.Now.ToString("T")
End Sub
End Class
O código HTML é inserido em [heure5.aspx]:
<%@ Page Inherits="heure5" %>
<html>
<head>
<title>Demo asp.net</title>
</head>
<body>
Il est
<% =maintenant %>
</body>
</html>
Desta vez, a diretiva [Page] não indica mais a relação entre o código HTML e o código VB. O servidor web não consegue mais localizar o código VB para compilá-lo (ausência do atributo src). Cabe a nós realizar essa compilação. Em uma janela do DOS, compilamos, portanto, as classes VB e [heure5.aspx.vb]:
dos>dir
23/03/2004 18:34 133 heure1.aspx
24/03/2004 09:47 232 heure2.aspx
24/03/2004 10:16 183 heure3.aspx
24/03/2004 10:16 332 heure3.aspx.vb
24/03/2004 14:31 440 heure4.aspx
24/03/2004 14:45 332 heure5.aspx.vb
24/03/2004 14:56 148 heure5.aspx
dos>vbc /r:system.dll /r:system.web.dll /t:library /out:heure5.dll heure5.aspx.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4
Acima, o executável [vbc.exe] do compilador estava no PATH do computador com DOS. Se não fosse assim, teria sido necessário fornecer o caminho completo para o arquivo [vbc.exe], localizado na árvore de pastas onde o SDK.NET foi instalado. As classes derivadas de [Page] requerem recursos presentes nos arquivos DLL e [system.dll, system.web.dll], daí a referência a esses arquivos por meio da opção /r do compilador. A opção /t:library serve para indicar que se deseja gerar um DLL. A opção /out indica o nome do arquivo a ser gerado, neste caso, [heure5.dll]. Esse arquivo contém a classe [heure5] necessária para o documento da web [heure5.aspx]. No entanto, o servidor web procura os arquivos DLL de que precisa em locais bem específicos. Um desses locais é a pasta [bin], localizada na raiz de sua árvore de diretórios. Essa raiz é o que chamamos de <webroot>. Para o servidor IIS, geralmente é <unidade>:\inetpub\wwwroot, onde <unidade> é a unidade (C, D, ...) em que o IIS foi instalado. Para o servidor Cassini, essa raiz corresponde ao parâmetro /path com o qual você o iniciou. Vale lembrar que esse valor pode ser obtido clicando duas vezes no ícone do servidor na barra de tarefas:

<webroot> corresponde ao atributo [Physical Path] mencionado acima. Portanto, criamos uma pasta <webroot>\bin e colocamos o [heure5.dll] nela:

Estamos prontos. Solicitamos o URL [http://localhost/aspnet/chap2/heure5.aspx] ao servidor Cassini (<webroot>,/aspnet):

3.3.6. Exemplo básico – variante 6
Ferramentas necessárias: um editor de texto, o servidor web Cassini
Mostramos até agora que uma aplicação web dinâmica possui dois componentes:
- código VB para calcular as partes dinâmicas da página
- código HTML, que às vezes inclui código VB para exibir esses valores na página. Essa parte representa a resposta enviada ao cliente da web.
O componente 1 é chamado de componente controlador da página e o componente 2, de componente de apresentação. O componente de apresentação deve conter o mínimo possível de código VB, ou até mesmo nenhum código VB. Veremos que isso é possível. Aqui, mostramos um exemplo em que há apenas um controlador e nenhum componente de apresentação. É o próprio controlador que gera a resposta para o cliente, sem a ajuda do componente de apresentação.
O código de apresentação fica assim:
Vemos que não há mais nenhum código HTML nele. A resposta é elaborada diretamente no controlador:
Public Class heure6
Inherits System.Web.UI.Page
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' elabora-se a resposta
Dim HTML As String
HTML = "<html><head><title>heure6</title></head><body>Il est "
HTML += Date.Now.ToString("T")
HTML += "</body></html>"
' envia-se a resposta
Response.Write(HTML)
End Sub
End Class
O controlador elabora aqui a resposta completa, em vez de apenas as partes dinâmicas dela. Além disso, ele a envia. Ele faz isso por meio da propriedade [Response], do tipo [HttpResponse], da classe [Page]. Trata-se de um objeto que representa a resposta enviada pelo servidor ao cliente. A classe [HttpResponse] possui um método [Write] para gravar no fluxo HTML, que será enviado ao cliente. Aqui, colocamos todo o fluxo HTML a ser enviado na variável [HTML] e enviamos essa variável ao cliente por meio de [Response.Write(HTML)].
Solicitamos a URL [http://localhost/aspnet/chap2/heure6.aspx] ao servidor Cassini (<webroot>,/aspnet):

3.3.7. Conclusão
A seguir, utilizaremos o método 3, que separa o código VB e o código HTML de um documento da Web dinâmico em dois arquivos distintos. Esse método tem a vantagem de dividir uma página da Web em dois componentes:
- um componente controlador, composto exclusivamente pelo código VB, para calcular as partes dinâmicas da página
- um componente de apresentação, que é a resposta enviada ao cliente. Ele é composto por código HTML, incluindo, às vezes, código VB para a exibição dos valores dinâmicos. Sempre buscaremos ter o mínimo possível de código VB na parte de apresentação, sendo o ideal não ter nenhum.
Conforme demonstrado no método 5, o controlador poderá ser compilado independentemente da aplicação web. Isso apresenta a vantagem de permitir concentrar-se exclusivamente no código e obter, a cada compilação, a lista de todos os erros. Depois que o controlador for compilado, a aplicação web poderá ser testada. Sem compilação prévia, será o servidor web que fará a compilação, e os erros serão sinalizados um por um. Isso pode ser considerado tedioso.
Para os exemplos a seguir, bastam as seguintes ferramentas:
- um editor de texto para criar os documentos HTML e VB do aplicativo, quando forem simples
- um IDE de desenvolvimento .NET para criar as classes VB.NET, a fim de aproveitar a ajuda que esse tipo de ferramenta oferece na escrita de código. Um exemplo dessa ferramenta é o CSharpDevelop (http://www.icsharpcode.net). Um exemplo de uso é apresentado no anexo [Les outils du développement web].
- a ferramenta WebMatrix para criar as páginas de apresentação do aplicativo (consulte o anexo [Les outils du développement web]).
- o servidor Cassini
Todas essas ferramentas são gratuitas.