5. Gerenciamento da interface do usuário
5.1. Introduction
Na relação cliente-servidor da web, o cliente transmite informações ao servidor na forma de uma cadeia de parâmetros [param1=val1¶m2=val2&...]. Em nossos exemplos anteriores, construímos essa cadeia, na maioria das vezes, manualmente, solicitando URLs do tipo [http://localhost/appli? param1=val1¶m2=val2&...]. Na prática, as informações que o cliente transmite ao servidor provêm de formulários preenchidos pelo usuário. Neste capítulo, exploramos a construção desses formulários. Também apresentamos a ferramenta WebMatrix, que nos permitirá projetar as interfaces de usuário. A instalação dessa ferramenta é apresentada nos anexos.
5.2. A linguagem HTML
5.2.1. Um exemplo
Consideremos o exemplo a seguir, criado com o [Web Matrix], que apresenta:
- uma tabela
- uma imagem
- um link

Vamos executar o [WebMatrix] e, em seguida, selecionar a opção [File/New File]:

Optamos por criar uma página HTML. As informações acima criarão um arquivo [d:\data\devel\aspnet\chap4\exemple1\exemple1.htm]. O [WebMatrix] oferece duas opções para editar esse arquivo: o modo [Design] e o modo [HTML]:

O modo [Design] permite utilizar a paleta de componentes HTML oferecida pelo [WebMatrix]:

Para inserir um elemento dessa paleta, basta clicar duas vezes nele e, em seguida, posicioná-lo na janela [Design]. O modo [HTML] permite criar o documento HTML com a ajuda de um editor de texto. Para isso, é necessário conhecer a sintaxe da linguagem HTML. Na aba [HTML], foi gerado um esboço de documento:

A janela [HTML] é muito útil para quem não conhece a linguagem HTML. Ele cria seu documento na janela [Design] e verifica o código HTML gerado na janela [HTML]. Dessa forma, o usuário vai adquirindo, aos poucos, o domínio da linguagem HTML e consegue, em pouco tempo, trabalhar apenas com o editor de texto, sem a ajuda do modo [Design]. Mostraremos agora como construir o documento HTML apresentado no início desta seção. Estamos trabalhando na janela [Design]. Primeiro, inserimos diretamente a primeira linha de texto:

- adicionamos o componente [Horizontal Rule] na paleta de componentes:

- adicionamos o componente [Table]:

- colocamos o cursor na terceira linha da tabela para excluí-la com a opção [HTML/Edit Table/Delete Table Row]. Em seguida, inserimos o texto desejado em cada célula:

- colocamos o cursor em uma das células da tabela e verificamos suas propriedades. A janela de propriedades é exibida no canto inferior direito da área de trabalho:

- a célula é representada pela tag HTML <TD>. Assim, são exibidas as propriedades da tag <TD>. Analisamos a tabela, que é um objeto que engloba a célula. Clicamos na lista suspensa (clique para ver os elementos pai HTML) acima para selecionar o objeto <TABLE>:

- O objeto <TABLE> possui uma propriedade [border] que define a largura da borda ao redor das células da tabela. Aqui, definimos border=1.

- Agora editamos os atributos do objeto <TD> da célula (1,2) para definir align=Center e width=200 (pixels). O texto ficará centralizado na célula (align=center) e esta terá 200 pixels de largura. Para visualizar a alteração, às vezes pode ser necessário selecionar a guia [HTML] e, em seguida, voltar para a guia [Design]:

- agora colocamos o texto que precede a imagem:

- e, em seguida, a imagem, clicando duas vezes no componente [image] da paleta:

- Selecionamos a imagem para editar suas propriedades:

- no atributo [src], inserimos o nome do arquivo que contém a imagem, neste caso [univ01.gif]:

- colocamos o texto que precede o link:

- transformamos o texto [ici] em um link para a URL [http://istia.univ-angers.fr]. Para isso, selecionamos o texto e escolhemos a opção [HTML/Insert Hyperlink]:

- obtemos o seguinte resultado:

- Estamos quase lá. Vamos dar uma olhada no código HTML gerado na aba [HTML]:
<html>
<head>
</head>
<body>
<p>
Le langage HTML - 1
</p>
<hr />
<table border="1">
<tbody>
<tr>
<td>
cellule(1,1)</td>
<td align="middle" width="200">
cellule(1,2)</td>
<td>
cellule(1,3)</td>
</tr>
<tr>
<td>
cellule(2,1)</td>
<td>
cellule(2,2)</td>
<td>
cellule(2,3)</td>
</tr>
</tbody>
</table>
<p>
Une image <img src="univ01.gif" />
</p>
<p>
Le site de l'istia <a href="http://istia.univ-angers.fr">ici</a>
</p>
</body>
</html>
Ainda precisamos resolver alguns detalhes. Em primeiro lugar, gostaríamos de dar um título ao nosso documento. O [WebMatrix] não permite fazer isso no modo [Design]. Na aba [HTML], substituímos a sequência <head>..</head> pela seguinte sequência:
Além disso, gostaríamos que o texto [Le langage HTML - 1] fosse exibido em caracteres maiores. A sequência <Hi>texto</Hi> permite definir o tamanho de um texto, com o valor de i variando de 1 a 6, do maior para o menor. Aqui, usaremos H2. A sequência
torna-se:
A janela [Design] reflete nossas alterações:

Agora só nos resta testar usando a opção [View/Start] ou [F5]. A opção [WebMatrix] solicita algumas informações para iniciar o servidor web [Cassini]:

Podemos aceitar os valores propostos por padrão. O servidor [Cassini] é iniciado e nossa página é exibida em um navegador:

Por curiosidade, podemos verificar com quais parâmetros o [Cassini] foi iniciado:

Apresentamos os fundamentos para a construção de uma página HTML com o [WebMatrix]. O leitor é convidado a construir outras páginas HTML e a verificar, a cada vez, o código HTML gerado. Aos poucos, ele será capaz de criar uma página sem a ajuda do modo [Design]. Um documento HTML tem o seguinte formato geral:
Todo o documento é delimitado pelas tags <html>...</html>. Ele é composto por duas partes:
<head>...</head>: essa é a parte não exibível do documento. Ela fornece informações ao navegador que irá exibir o documento. Nela, costuma-se encontrar a tag <title>...</title>, que define o texto a ser exibido na barra de título do navegador. Também podem ser encontradas outras tags, notadamente aquelas que definem as palavras-chave do documento, palavras-chave posteriormente utilizadas pelos mecanismos de busca. Também é possível encontrar nessa parte scripts, geralmente escritos em JavaScript ou VBScript, que serão executados pelo navegador.
<body atributos>...</body>: esta é a parte que será exibida pelo navegador. As tags HTML contidas nesta parte indicam ao navegador a forma visual “desejada” para o documento. Cada navegador interpretará essas tags à sua maneira. Dois navegadores podem, portanto, exibir um mesmo documento da web de maneiras diferentes. Isso costuma ser um dos desafios dos web designers.
O código HTML do documento anterior era o seguinte:
<html>
<head>
<title>HTML1</title>
</head>
<body>
<h2>Le langage HTML - 1
</h2>
<hr />
<table border="1">
<tbody>
<tr>
<td>
cellule(1,1)</td>
<td align="middle" width="200">
cellule(1,2)</td>
<td>
cellule(1,3)</td>
</tr>
<tr>
<td>
cellule(2,1)</td>
<td>
cellule(2,2)</td>
<td>
cellule(2,3)</td>
</tr>
</tbody>
</table>
<p>
Une image <img src="univ01.gif" />
</p>
<p>
Le site de l'istia <a href="http://istia.univ-angers.fr">ici</a>
</p>
</body>
</html>
Elemento | tags e exemplos HTML |
<title>HTML1</title> HTML1 aparecerá na barra de título do navegador que exibirá o documento | |
<hr>: exibe uma linha horizontal | |
<atributos da tabela>....</table>: para definir a tabela <tr atributos>...</tr>: para definir uma linha <td atributos>...</td>: para definir uma célula exemplos: <table border="1">...</table>: o atributo border define a espessura da borda da tabela <td align="center" width="200">célula(1,2)</td>: define uma célula cujo conteúdo será cellule(1,2). Esse conteúdo será centralizado horizontalmente (align="center"). A célula terá uma largura de 200 pixels (width="200") | |
<img src="univ01.gif" />: define uma imagem cujo arquivo de origem é univ01.gif no servidor web (src="univ01.gif"). Esse link está em um documento da web gerado com o URL http://localhost/exemple1.htm. Assim, o navegador solicitará o URL http://localhost/univ01.gif para obter a imagem referenciada aqui. | |
<a href="http://istia.univ-angers.fr">aqui</a>: faz com que o texto ici sirva como link para o URL http://istia.univ-angers.fr. |
Vemos neste exemplo simples que, para construir o documento na íntegra, o navegador precisa fazer duas solicitações ao servidor:
http://localhost/exemple1.htm para obter o código-fonte HTML do documento
http://localhost/univ01.gif para obter a imagem univ01.gif
5.2.2. Criação de um formulário
Um formulário HTML tem como objetivo apresentar ao usuário uma página de preenchimento de informações semelhante aos formulários encontrados no Windows. O formulário de preenchimento é enviado ao navegador na forma de um documento HTML. Este apresentará o formulário ao usuário, que o preencherá e o validará por meio de um botão com essa função. O navegador, então, transmitirá os valores inseridos ao servidor para processamento. Veremos que ele não envia ao servidor o formulário completo, mas apenas os valores inseridos. O exemplo a seguir apresenta um formulário da Web também criado com WebMatrix:

O código HTML gerado pelo [WebMatrix] é o seguinte:
<html>
<head>
<title>Formulaire</title>
<script language="javascript">
function effacer(){
alert("Vous avez cliqué sur le bouton [Effacer]");
}
</script>
</head>
<body>
<p>
Gestion d'un formulaire
</p>
<hr />
<form name="formulaire" method="post">
<table border="1">
<tr>
<td>
Etes-vous marié(e)</td>
<td>
<p align="center">
<input type="radio" value="oui" name="rdMarie" />Oui
<input type="radio" checked value="non" name="rdMarie" />Non
</p>
</td>
</tr>
<tr>
<td>
Cases à cocher
</td>
<td>
<p align="center">
<input type="checkbox" value="un" name="C1" />1
<input type="checkbox" checked value="deux" name="C2" />2
<input type="checkbox" value="trois" name="C3" />3
</p>
</td>
</tr>
<tr>
<td>
Champ de saisie</td>
<td>
<p align="center">
<input type="text" maxlength="30" value="qqs mots" name="txtSaisie" />
</p>
</td>
</tr>
<tr>
<td>
Mot de passe</td>
<td>
<p align="center">
<input type="password" maxlength="12" size="12" value="unMotDePasse" name="txtMdp" />
</p>
</td>
</tr>
<tr>
<td>
Boîte de saisie</td>
<td>
<p align="center">
</p>
<textarea name="areaSaisie">ligne1
ligne2</textarea>
</td>
</tr>
<tr>
<td>
ComboBox</td>
<td>
<p align="center">
</p>
<select name="cmbValeurs">
<option value="1">choix1</option>
<option value="2" selected>choix2</option>
<option value="3">choix3</option>
</select>
</td>
</tr>
<tr>
<td>
Liste à choix simple</td>
<td>
<p align="center">
</p>
<select size="3" name="lstSimple">
<option value="1" selected>liste1</option>
<option value="2">liste2</option>
<option value="3">liste3</option>
<option value="4">liste4</option>
<option value="5">liste5</option>
</select>
</td>
</tr>
<tr>
<td>
Liste à choix multiple</td>
<td>
<p align="center">
</p>
<select multiple size="3" name="lstMultiple">
<option value="1" selected>multiple1</option>
<option value="2">multiple2</option>
<option value="3" selected>multiple3</option>
<option value="4">multiple4</option>
<option value="5">multiple5</option>
</select>
</td>
</tr>
<tr>
<td>
Bouton simple</td>
<td>
<p align="center">
<input onclick="effacer()" type="button" value="Effacer" name="btnEffacer" />
</p>
</td>
</tr>
<tr>
<td>
Bouton submit</td>
<td>
<p align="center">
<input type="submit" value="Envoyer" name="btnEnvoyer" />
</p>
</td>
</tr>
<tr>
<td>
Bouton reset</td>
<td>
<p align="center">
<input type="reset" value="Rétablir" name="btnRetablir" runat="server" />
</p>
</td>
</tr>
</table>
<input type="hidden" name="secret" value="uneValeur" />
</form>
</body>
</html>
A correspondência entre a verificação visual e a baliza HTML é a seguinte:
Controle | tag HTML |
<form name="formulário" method="post"> | |
<input type="text" maxlength="30" value="algumas palavras" name="txtSaisie" /> | |
<input type="password" maxlength="12" size="12" value="unMotDePasse" name="txtMdp" /> | |
<textarea name="areaSaisie">linha1 linha2</textarea> | |
<input type="radio" value="sim" name="rdMarie" />Sim <input type="radio" checked value="não" name="rdMarie" />Não | |
<input type="checkbox" value="um" name="C1" />1 <input type="checkbox" checked value="dois" name="C2" />2 <input type="checkbox" value="três" name="C3" />3 | |
<select name="cmbValeurs"> <option value="1">opção1</option> <option value="2" selected>opção 2</option> <option value="3">opção 3</option> </select> | |
<select size="3" name="lstSimple"> <option value="1" selected>lista1</option> <option value="2">lista2</option> <option value="3">lista3</option> <option value="4">lista4</option> <option value="5">lista5</option> </select> | |
<select multiple size="3" name="lstMultiple"> <option value="1" selected>múltiplo1</option> <option value="2">múltiplo2</option> <option value="3" selected>multiple3</option> <option value="4">multiple4</option> <option value="5">multiple5</option> </select> | |
<input type="hidden" name="secret" value="uneValeur" /> | |
<input type="submit" value="Enviar" name="btnEnvoyer" /> | |
<input type="reset" value="Redefinir" name="btnRetablir" runat="server" /> | |
<input onclick="effacer()" type="button" value="Apagar" name="btnEffacer" /> |
Vamos examinar esses diferentes controles.
5.2.2.1. O formulário
<form name="formulário" method="post"> |
<form name="..." method="..." action="...">...</form> | |
name="frmexemple": nome do formulário method="..." : método utilizado pelo navegador para enviar ao servidor web os valores coletados no formulário action="..." : URL para onde serão enviados os valores coletados no formulário. Um formulário da web é delimitado pelas tags <form>...</form>. O formulário pode ter um nome (name="xx"). Isso se aplica a todos os controles que podem ser encontrados em um formulário. Esse nome é útil se o documento da web contiver scripts que precisem referenciar elementos do formulário. O objetivo de um formulário é coletar informações fornecidas pelo usuário por meio do teclado/mouse e enviá-las para uma URL do servidor web. Qual? Aquela referenciada no atributo action="URL". Se esse atributo estiver ausente, as informações serão enviadas para o servidor do documento no qual o formulário está localizado. Como um cliente web transmite informações (aquelas contidas no formulário) a um servidor web? Já vimos isso em detalhes. Ele pode utilizar dois métodos diferentes, chamados POST e GET. O atributo method="méthode", com o método igual a GET ou POST, da tag <form> indica ao navegador o método a ser utilizado para enviar as informações coletadas no formulário para o URL especificado pelo atributo action="URL". Quando o atributo method não é especificado, o método GET é utilizado por padrão. |
5.2.2.2. Campo de entrada

<input type="text" maxlength="30" value="algumas palavras" name="txtSaisie" /> <input type="password" maxlength="12" size="12" value="unMotDePasse" name="txtMdp" /> |
<input type="..." name="..." size=".." value=".."> A tag `input` existe para diversos controles. É o atributo type que permite diferenciar esses controles uns dos outros. | |
type="text": especifica que se trata de um campo de entrada type="password": os caracteres presentes no campo de entrada são substituídos por asteriscos (*). Essa é a única diferença em relação ao campo de entrada normal. Esse tipo de controle é adequado para a digitação de senhas. size="12": número de caracteres visíveis no campo — não impede a digitação de mais caracteres maxlength="30": define o número máximo de caracteres em 30 — cabe ao navegador garantir que esse atributo seja respeitado name="txtSaisie": nome do campo de entrada value="algumas palavras": texto que será exibido no campo de entrada. |
5.2.2.3. Campo de entrada com várias linhas

<textarea name="areaSaisie">linha1 linha2</textarea> |
<textarea ...>texto</textarea> exibe uma área de entrada de várias linhas com texto preenchido inicialmente | |
rows="2": número de linhas cols="'20": número de colunas name="areaSaisie": nome do controle |
5.2.2.4. Botões de opção
![]()
<input type="radio" value="sim" name="rdMarie" />Sim <input type="radio" checked value="não" name="rdMarie" />Não |
<input type="radio" atributo2="valor2" ..../>texto exibe um botão de opção com texto ao lado. | |
name="rdMarie": nome do controle. Os botões de opção com o mesmo nome formam um grupo de botões mutuamente exclusivos: só é possível selecionar um deles. value="valor": valor atribuído ao botão de opção. Não se deve confundir esse valor com o texto exibido ao lado do botão de opção. Este último destina-se apenas à exibição. checked: se essa palavra-chave estiver presente, o botão de opção estará marcado; caso contrário, não estará. |
5.2.2.5. Caixas de seleção
<input type="checkbox" value="um" name="C1" />1 <input type="checkbox" checked value="dois" name="C2" />2 <input type="checkbox" value="três" name="C3" />3 |
![]()
<input type="checkbox" atributo2="valor2" ..../>texto exibe uma caixa de seleção com texto ao lado. | |
name="C1": nome do controle. As caixas de seleção podem ou não ter o mesmo nome. As caixas com o mesmo nome formam um grupo de caixas associadas. value="valor": valor atribuído à caixa de seleção. Não se deve confundir esse valor com o texto exibido ao lado do botão de opção. Este último destina-se apenas à exibição. checked: se essa palavra-chave estiver presente, o botão de opção estará marcado; caso contrário, não estará. |
5.2.2.6. Lista suspensa (combo)
<select name="cmbValeurs"> <option value="1">opção1</option> <option value="2" selected>opção 2</option> <option value="3">opção 3</option> </select> |
![]()
<select size=".." name=".."> <option [selected="selected"] [value="valeur"]>texto</option> ... </select> exibe em uma lista os textos contidos entre as tags <option>...</option> | |
name="cmbValeurs": nome do controle. size="1": número de itens visíveis na lista. size="1" transforma a lista no equivalente a uma caixa de combinação. Esse é o valor padrão caso o atributo [size] esteja ausente. selected="selected": se essa palavra-chave estiver presente em um item da lista, ele aparecerá selecionado na lista. No exemplo acima, o item da lista choix2 aparece como o item selecionado na lista suspensa quando esta é exibida pela primeira vez. value="valor": define o valor a ser enviado ao servidor caso o elemento seja selecionado. Se esse atributo estiver ausente, o texto associado à opção será enviado ao servidor. |
5.2.2.7. Lista de seleção única
<select size="3" name="lstSimple"> <option value="1" selected>lista1</option> <option value="2">lista2</option> <option value="3">lista3</option> <option value="4">lista4</option> <option value="5">lista5</option> </select> |

<select size=".." name=".."> <option [selected] [value="valeur"]>...</option> ... </select> exibe em uma lista os textos entre as tags <option>...</option> | |
os mesmos da lista suspensa que exibe apenas um item. Esse controle difere da lista suspensa anterior apenas pelo atributo size>1. |
5.2.2.8. Lista de seleção múltipla
<select multiple size="3" name="lstMultiple"> <option value="1" selected>multiple1</option> <option value="2">multiple2</option> <option value="3" selected>multiple3</option> <option value="4">multiple4</option> <option value="5">multiple5</option> </select> |

<select size=".." name=".." multiple> <option [selected] ] [value="valeur"]>...</option> ... </select> exibe em uma lista os textos entre as tags <option>...</option> | |
múltiplo: permite a seleção de vários elementos na lista. No exemplo acima, os elementos liste1 e liste3 estão ambos selecionados. |
5.2.2.9. Botão do tipo button
<input onclick="effacer()" type="button" value="Apagar" name="btnEffacer" /> |
![]()
<input type="button" value="..." name="..." onclick="effacer()" ....> | |
type="button": define um controle de botão. Existem outros dois tipos de botão: os tipos submit e reset. value="Apagar": o texto exibido no botão onclick="função()": permite definir uma função a ser executada quando o usuário clica no botão. Essa função faz parte dos scripts definidos no documento da web exibido. A sintaxe anterior segue a sintaxe javascript. Se os scripts forem escritos em VBScript, deve-se escrever onclick="função" sem os parênteses. A sintaxe permanece a mesma caso seja necessário passar parâmetros para a função: onclick="função(val1, val2,...)" No nosso exemplo, um clique no botão Effacer chama a seguinte função JavaScript effacer: A função effacer exibe uma mensagem: ![]() |
5.2.2.10. Botão do tipo “submit”
<input type="submit" value="Enviar" name="btnEnvoyer" /> |
![]()
<input type="submit" value="Enviar" name="btnEnvoyer"> | |
type="submit": define o botão como um botão para enviar os dados do formulário ao servidor web. Quando o usuário clicar nesse botão, o navegador enviará os dados do formulário para o URL definido no atributo action da tag <form>, de acordo com o método definido pelo atributo method dessa mesma tag. value="Enviar": o texto exibido no botão |
5.2.2.11. Botão do tipo reset
<input type="reset" value="Restaurar" name="btnRetablir" runat="server" /> |
![]()
<input type="reset" value="Restaurar" name="btnRetablir"> | |
type="reset": define o botão como um botão de reinicialização do formulário. Quando o usuário clicar nesse botão, o navegador restaurará o formulário ao estado em que o recebeu. value="Restaurar": o texto exibido no botão |
5.2.2.12. Campo oculto
<input type="hidden" name="secret" value="uneValeur" /> |
<input type="hidden" name="..." value="..."> | |
type="hidden": indica que se trata de um campo oculto. Um campo oculto faz parte do formulário, mas não é exibido ao usuário. No entanto, se o usuário solicitar ao navegador que exiba o código-fonte, ele verá a presença da tag <input type="hidden" value="..."> e, portanto, o valor do campo oculto. value="umValor": valor do campo oculto. Qual é a utilidade do campo oculto? Ele permite que o servidor web armazene informações ao longo das solicitações de um cliente. Consideremos um aplicativo de compras na web. O cliente compra um primeiro item art1 na quantidade q1 na primeira página de um catálogo e, em seguida, passa para uma nova página do catálogo. Para lembrar que o cliente comprou q1 itens art1, o servidor pode inserir essas duas informações em um campo oculto do formulário da nova página. Nessa nova página, o cliente compra os itens q2 e art2. Quando os dados desse segundo formulário forem enviados ao servidor (submit), este receberá não apenas a informação (q2, art2), mas também (q1, art1), que também faz parte do formulário como um campo oculto não modificável pelo usuário. O servidor web irá então inserir em um novo campo oculto as informações (q1,art1) e (q2,art2) e enviar uma nova página do catálogo. E assim por diante. |
5.3. Envio dos valores de um formulário de um navegador para um servidor web
Já sabemos, graças ao capítulo anterior, como um cliente transmite informações ao servidor. Ele faz isso por meio de:
- uma solicitação com a URL HTTP GET?param1=va1¶m2=val2&....
- uma solicitação HTT POST url seguida de um documento contendo a sequência de parâmetros param1=va1¶m2=val2&....
O navegador utilizará um desses dois métodos, dependendo se o atributo [method] da tag [form] for GET ou POST. É isso que vamos mostrar agora. A página analisada anteriormente é uma página estática. Para ter acesso aos cabeçalhos HTTP enviados pelo navegador que solicitará esse documento, vamos transformá-la em uma página dinâmica para um servidor web .NET (IIS ou Cassini). O código estático anterior é colocado em um arquivo [formulaire_get.aspx] e seu conteúdo é o seguinte:
<%@ Page src="formulaire_get.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="formulaire_get" %>
<html>
<head>
<title>Formulaire</title>
<script language="javascript">
function effacer(){
alert("Vous avez cliqué sur le bouton [Effacer]");
}
</script>
</head>
<body>
.....
</body>
</html>
A página de apresentação acima está associada ao controlador [formulaire_get.aspx.vb]:
Public Class formulaire_get
Inherits System.Web.UI.Page
Private Sub Page_Init(ByVal Sender As Object, ByVal e As System.EventArgs) Handles MyBase.Init
' salva a solicitação atual em request.txt na pasta da página
Dim requestFileName As String = Me.MapPath(Me.TemplateSourceDirectory) + "\request.txt"
Me.Request.SaveAs(requestFileName, True)
End Sub
End Class
A cada chamada do documento [formulaire_get.aspx], a solicitação do cliente será salva em um arquivo [request.txt] pelo procedimento Page_Init. Já nos deparamos com esse modo de funcionamento, portanto não faremos mais comentários sobre o controlador.
5.3.1. Método GET
Vamos fazer um primeiro teste, no qual, no código HTML do documento, a tag FORM é definida da seguinte forma:
<form name="formulaire" method="get">
Colocamos os arquivos [formulaire_get.aspx] e [formulaire_get.aspx.vb] em uma pasta <application-path> e iniciamos o servidor Cassini com os parâmetros (<application-path>,/form2). Acessamos a URL http://localhost/form2/formulaire_get.aspx:

O navegador acabou de fazer uma solicitação e sabemos que ela foi registrada no arquivo [request.txt]. Vamos verificar o conteúdo desse arquivo:
GET /form2/formulaire_get.aspx HTTP/1.1
Cache-Control: max-age=0
Connection: keep-alive
Keep-Alive: 300
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7b) Gecko/20040316
O navegador utilizou uma solicitação HTTP GET para solicitar a URL [http://localhost/form2/formulaire_get.aspx]. Isso sempre ocorre quando a URL é fornecida pelo usuário. Preenchemos o formulário da seguinte maneira:

Usamos o botão [Envoyer] acima. Seu código HTML é o seguinte:
Ao clicar em um botão do tipo [Submit], o navegador envia os parâmetros do formulário (tag <form>) para o URL indicado no atributo [action] da tag <form action="URL">, caso exista. Se esse atributo não existir, os parâmetros do formulário são enviados para o URL que gerou o formulário. É o que ocorre neste caso. O botão [Envoyer] deve, portanto, gerar uma solicitação do navegador para o URL [http://localhost/form2/formulaire_get.aspx] com o envio dos parâmetros do formulário. Como a página [formulaire_get.aspx] armazena a solicitação recebida, deveríamos saber como o cliente transferiu esses parâmetros. Vamos tentar. Clicamos no botão [Envoyer]. Recebemos a seguinte resposta do navegador:

Essa é a página inicial, mas podemos observar que o valor URL mudou no campo [Adresse] do navegador. Ele ficou assim:
http://localhost/form2/formulaire_get.aspx?rdMarie=sim&C1=um&C2=dois&txtSaisie=programação+asp.net&txtMdp=unMotDePasse&areaSaisie=os+fundamentos+da%0D%0Aprogramação+web%0D%0A&cmbValeurs=3&lstSimple=1&lstMultiple=2&lstMultiple=4&btnEnvoyer=Enviar&secret=uneValeur
Percebe-se que as opções selecionadas no formulário aparecem no URL. Vejamos o conteúdo do arquivo [request.txt], que armazenou a solicitação do cliente:
GET /form2/formulaire_get.aspx?rdMarie=oui&C1=un&C2=deux&txtSaisie=programmation+asp.net&txtMdp=ceciestsecre&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web%0D%0A&cmbValeurs=3&lstSimple=1&lstMultiple=2&lstMultiple=4&btnEnvoyer=Envoyer&secret=uneValeur HTTP/1.1
Connection: keep-alive
Keep-Alive: 300
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0,1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
Referer: http://localhost/form2/formulaire_get.aspx
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7b) Gecko/20040316
Encontramos uma solicitação HTTP bastante semelhante à que havia sido feita inicialmente pelo navegador quando ele solicitou o documento sem enviar parâmetros. Há duas diferenças:
Os parâmetros do formulário foram adicionados após o URL do documento na forma ?param1=val1¶m2=val2&... | |
O cliente indica, por meio desse cabeçalho HTTP, o URL do documento que estava exibindo quando fez a solicitação |
Vamos examinar mais de perto como os parâmetros foram passados no comando GET URL?param1=valor1¶m2=valor2&... HTTP/1.1, em que parami são os nomes dos controles do formulário da web e valeuri os valores a eles associados. Apresentamos abaixo uma tabela com três colunas:
- coluna 1: apresenta a definição de um controle HTML do exemplo
- coluna 2: mostra como esse controle é exibido em um navegador
- coluna 3: apresenta o valor enviado ao servidor pelo navegador para o controle da coluna 1, na forma em que aparece na solicitação GET do exemplo
controle HTML | visualização antes da validação | valor(es) retornado(s) |
<input type="radio" value="sim" name="rdMarie" />Sim <input type="radio" checked value="não" name="rdMarie" />Não | rdMarie=sim - o valor do atributo value do botão marcado pelo usuário. | |
<input type="checkbox" value="um" name="C1" />1 <input type="checkbox" checked value="dois" name="C2" />2 <input type="checkbox" value="três" name="C3" />3 | C1=um C2=dois - valores dos atributos value das caixas de seleção marcadas pelo usuário | |
<input type="text" maxlength="30" value="algumas palavras" name="txtSaisie" /> | txtSaisie=programação+asp.net - texto digitado pelo usuário no campo de entrada. Os espaços foram substituídos pelo sinal + | |
<input type="password" maxlength="12" size="12" value="umaSenha" name="txtMdp" /> | txtMdp=issoésecreto - texto digitado pelo usuário no campo de entrada. O texto realmente digitado era “issoésegredo”. O último caractere foi perdido porque o atributo maxlength="12" limitava o número de caracteres a 12. | |
<textarea name="areaSaisie"> linha1 linha2</textarea> | ![]() | áreaDeDigitação=os+fundamentos+de+ da%0D%0A programação+web - texto digitado pelo usuário no campo de entrada. %OD%OA é a marca de fim de linha. Os espaços foram substituídos pelo sinal + |
<select name="cmbValeurs"> <option value="1">opção1 </option> <option value="2" selected>opção 2 </option> <option value="3">opção 3 </option> </select> | cmbValores=3 - valor escolhido pelo usuário na lista de seleção única | |
<select size="3" name="lstSimple"> <option value="1" selected>lista1</option> <option value="2">lista2 </option> <option value="3">lista3 </option> <option value="4">lista4 </option> <option value="5">lista5 </option> </select> | ![]() | lstSimple=3 - valor escolhido pelo usuário na lista de seleção única |
<select multiple size="3" name="lstMultiple"> <option value="1" selected>multiple1 </option> <option value="2">multiple2 </option> <option value="3" selected>multiple3 </option> <option value="4">múltiplo4 </option> <option value="5">multiple5 </option> </select> | ![]() | lstMultiple=2 lstMultiple=4 - valores selecionados pelo usuário na lista de seleção múltipla |
<input type="submit" value="Enviar" name="btnEnviar" /> | btnEnvoyer=Enviar - nome e atributo value do botão que serviu para enviar os dados do formulário para o servidor | |
<input type="hidden" name="secret" value="umValor" /> | secret=umValor - atributo value do campo oculto |
Podemos nos perguntar o que o servidor fez com os parâmetros que lhe foram passados. Na verdade, nada. Ao receber o comando
GET /form2/formulaire_get.aspx?rdMarie=oui&C1=un&C2=deux&txtSaisie=programmation+asp.net&txtMdp=ceciestsecre&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web%0D%0A&cmbValeurs=3&lstSimple=1&lstMultiple=2&lstMultiple=4&btnEnvoyer=Envoyer&secret=uneValeur HTTP/1.1
O servidor web transmitiu os parâmetros do URL para os documentos [http://localhost/form2/formulaire_get.aspx] e c.a.d, que criamos inicialmente. Não escrevemos nenhum código para recuperar e processar os parâmetros que o cliente nos envia. Portanto, tudo ocorre como se a solicitação do cliente fosse simplesmente:
É por esse motivo que, em resposta ao nosso botão [Envoyer], obtivemos a mesma página que a obtida inicialmente ao solicitar o URL [http://localhost/form2/formulaire_get.aspx] sem parâmetros.
5.3.2. Método POST
O documento HTML está agora configurado para que o navegador utilize o método POST para enviar os valores do formulário ao servidor web. Para isso, copiamos o arquivo [formulaire_get.aspx] para [formulaire_post.aspx] e alteramos apenas a tag <form> em [formulaire_post.aspx]:
<%@ Page src="formulaire_get.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="formulaire_get" %>
<html>
<head>
...
</head>
<body>
<p>
Gestion d'un formulaire
</p>
<hr />
<form name="formulaire" method="post">
<table border="1">
Não há necessidade de trocar o controlador [formulaire_get.aspx.vb]; portanto, vamos mantê-lo como está. Solicitamos o novo documento por meio do URL [http://localhost/form2/formulaire_post.aspx], preenchemos o formulário da mesma forma que no método GET e enviamos os parâmetros ao servidor com o botão [Envoyer]. Recebemos do servidor a seguinte página de resposta:

Assim, obtemos o mesmo resultado que com os métodos GET e c.a.d: a página inicial. Notamos uma diferença: no campo [Adresse] do navegador, os parâmetros transmitidos não aparecem. Agora, vamos examinar a solicitação enviada pelo cliente e que foi armazenada no arquivo [request.txt]:
POST /form2/formulaire_post.aspx HTTP/1.1
Connection: keep-alive
Keep-Alive: 300
Content-Length: 222
Content-Type: application/x-www-form-urlencoded
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0,1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
Referer: http://localhost/form2/formulaire_post.aspx
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7b) Gecko/20040316
rdMarie=oui&C1=un&C2=deux&txtSaisie=programmation+asp.net&txtMdp=ceciestsecre&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web%0D%0A&cmbValeurs=3&lstSimple=3&lstMultiple=2&lstMultiple=4&btnEnvoyer=Envoyer&secret=uneValeur
Novidades na consulta HTTP do cliente:
a consulta GET foi substituída pela consulta POST. Os parâmetros não estão mais presentes nesta primeira linha da consulta. É possível observar que agora eles estão posicionados após a consulta HTTP, após uma linha em branco. Sua codificação é idêntica à que tinham na consulta GET. | |
número de caracteres “enviados”, c.a.d. O número de caracteres que o servidor web deverá ler após receber os cabeçalhos HTTP para recuperar o documento enviado pelo cliente. O documento em questão é, neste caso, a lista de valores do formulário. | |
especifica o tipo de documento que o cliente enviará após os cabeçalhos HTTP. O tipo [application/x-www-form-urlencoded] indica que se trata de um documento contendo valores de formulário. |
Existem dois métodos para transmitir dados a um servidor web: GET e POST. Existe um método melhor do que o outro? Vimos que, se os valores de um formulário fossem enviados pelo navegador com o método GET, o navegador exibia em seu campo Adresse o URL solicitado na forma URL?param1=val1¶m2=val2&.... Isso pode ser visto como uma vantagem ou uma desvantagem:
- uma vantagem se quisermos permitir que o usuário salve esse URL configurado em seus favoritos
- uma desvantagem se não quisermos que o usuário tenha acesso a certas informações do formulário, como, por exemplo, os campos ocultos
Daqui em diante, utilizaremos quase exclusivamente o método POST em nossos formulários.
5.4. Processamento no servidor dos valores de um formulário
5.4.1. Apresentação do exemplo
Agora que estabelecemos a relação entre a tag HTML <form method="GET/POST" ...> e a forma como o navegador envia os valores do formulário, sabemos como recuperá-los no lado do servidor. Foi o capítulo anterior que nos deu a resposta:
- se o método da tag <form> for GET, os valores dos parâmetros serão recuperados na coleção [Request.QueryString]
- se o método da tag <form> for POST, os valores dos parâmetros “enviados” serão recuperados na coleção [Request.Form]. É preciso fazer aqui uma precisão. A tag <form> pode especificar, por meio do atributo [action], a URL de destino do GET ou do POST. Essa URL pode muito bem ser configurada, independentemente de se tratar de um GET ou de um POST, na forma action="url?param1=val1¶m2=val2&..". Esses parâmetros são então adicionados aos que estão entre as tags <form> e </form> e que serão transferidos para o servidor por meio de um GET ou de um POST. Como fazem parte da URL de destino, eles serão obtidos na coleção [Request.QueryString], independentemente de se tratar de um GET ou de um POST.
Agora, vamos criar um aplicativo MVC com duas visualizações:
- a primeira visualização é o formulário anterior. Vamos chamá-la de [vue_formulaire].
- a segunda tela é uma página de informações que lista os valores inseridos na primeira página. Um link permite retornar ao formulário. Chamaremos essa tela de [vue_confirmation].
A visualização [vue_formulaire] é enviada ao usuário, que a preenche e a valida. Ela poderia se parecer com isto logo antes da validação:

O usuário utiliza o botão [Envoyer] para validar suas entradas. Em resposta, ele recebe a seguinte visualização [vue_validation]:

5.4.2. O controlador da aplicação
Vimos no capítulo anterior que podemos atribuir a função de controlador de uma aplicação MVC ao arquivo [global.asax], pelo qual passam todas as solicitações dos clientes. Já apresentamos uma aplicação MVC construída dessa forma e, aqui, seguimos o modelo de desenvolvimento apresentado na ocasião. O arquivo [global.asax] terá a seguinte estrutura:
Ele é composto por uma única linha que faz referência ao controlador localizado no arquivo [global.asax.vb]:
Imports System
Imports System.Web
Imports System.Web.SessionState
Public Class Global
Inherits System.Web.HttpApplication
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
' recupera-se a ação a ser realizada
Dim action As String
If Request.QueryString("action") Is Nothing Then
action = "init"
Else
action = Request.QueryString("action").ToString.ToLower
End If
' executa-se a ação
Select Case action
Case "init"
Server.Transfer("formulaire.aspx", False)
Case "validation"
Server.Transfer("validation.aspx", True)
Case Else
Server.Transfer("formulaire.aspx", True)
End Select
End Sub
End Class
O princípio do controlador é o seguinte:
- ele aguarda, na URL de destino, uma sequência de parâmetros que contenha o parâmetro [action]. Se este estiver ausente, trata-se como se tivéssemos [action=init] na sequência de parâmetros.
- Apenas duas ações são reconhecidas:
- init: o formulário pré-preenchido é enviado ao cliente
- validação: é exibida ao cliente a página que confirma os dados inseridos
- Se a ação não for uma das anteriores, trata-se como se tivéssemos [action=init]. Também seria possível exibir uma página de erro.
5.4.3. Processamento da ação init
Quando o controlador processa a ação “init”, ele deve gerar um formulário pré-preenchido. Cabe à página [formulaire.aspx] realizar essa tarefa. Seu código é o seguinte:
<HTML>
<HEAD>
<title>Formulaire</title>
<script language="javascript">
function effacer(){
alert("Vous avez cliqué sur le bouton [Effacer]");
}
function raz(liste){
liste.selectedIndex=-1
}
</script>
</HEAD>
<body>
<p>
Gestion d'un formulaire
</p>
<hr>
<form name="formulaire" method="post" action="?action=validation">
<table border="1">
<tr>
<td>
Etes-vous marié(e)</td>
<td>
<p align="center">
<input type="radio" value="oui" name="rdMarie">Oui <input type="radio" checked value="non" name="rdMarie">Non
</p>
</td>
</tr>
....
<td>
<select size="3" name="lstSimple">
<option value="1" selected>liste1</option>
<option value="2">liste2</option>
<option value="3">liste3</option>
<option value="4">liste4</option>
<option value="5">liste5</option>
</select>
<INPUT type="button" value="Raz" name="btnRazSimple" onclick="raz(lstSimple)">
</td>
....
<td>
<select multiple size="3" name="lstMultiple">
<option value="1" selected>multiple1</option>
<option value="2">multiple2</option>
<option value="3" selected>multiple3</option>
<option value="4">multiple4</option>
<option value="5">multiple5</option>
</select>
<INPUT type="button" value="Raz" name="btnRazMultiple" onclick="raz(lstMultiple)">
</td>
...
</table>
<input type="hidden" name="secret" value="uneValeur">
</form>
</body>
</HTML>
Encontramos o código HTML do formulário analisado anteriormente, com algumas pequenas diferenças. O código da tag <form> foi alterado:
<form name="formulaire" method="post" action="?action=validation">
- post: os valores inseridos pelo usuário e enviados ao servidor quando o botão do tipo [submit] for utilizado serão processados pelo método HTTP POST
- ação: a sintaxe action="url" serve para indicar a URL para a qual os valores do formulário devem ser enviados. Essa URL pode conter uma sequência de parâmetros no formato param1=val1¶m2=val2&... É isso que é feito aqui, onde passamos o parâmetro [action=validation] para indicar ao controlador a ação que ele deve realizar. Vale notar que essa sequência de parâmetros não é precedida por um endereço da web. O navegador enviará, então, os parâmetros do formulário para o endereço que lhe forneceu esse formulário. No exemplo apresentado acima, esse endereço é [http://localhost/mvcform1]. O navegador, portanto, fará uma solicitação [POST /mvcform1?action=validation] ao servidor [localhost].
Foram adicionados botões para permitir que o usuário desmarque os itens das listas [lstSimple] e [lstMultiple]:

Isso resulta no seguinte código HTML:
<td>
<select size="3" name="lstSimple">
<option value="1" selected>liste1</option>
<option value="2">liste2</option>
<option value="3">liste3</option>
<option value="4">liste4</option>
<option value="5">liste5</option>
</select>
<INPUT type="button" value="Raz" name="btnRazSimple" onclick="raz(lstSimple)">
</td>
....
<td>
<select multiple size="3" name="lstMultiple">
<option value="1" selected>multiple1</option>
<option value="2">multiple2</option>
<option value="3" selected>multiple3</option>
<option value="4">multiple4</option>
<option value="5">multiple5</option>
</select>
<INPUT type="button" value="Raz" name="btnRazMultiple" onclick="raz(lstMultiple)">
</td>
Um clique no botão [Raz] faz com que todos os itens da lista à qual ele está associado sejam desmarcados. Tomemos como exemplo a lista [lstMultiple]. Ao clicar no botão [Raz] correspondente, a função JavaScript [raz(lstMultiple)] é executada. Vale lembrar que o código JavaScript de um documento HTML exibido por um navegador é executado por esse mesmo navegador e não pelo servidor. O JavaScript é uma linguagem muito completa que permite conferir um aspecto dinâmico às páginas sem a intervenção do servidor. A função [raz] é a seguinte:
Essa função recebe um parâmetro que é um objeto JavaScript representando uma lista HTML. Esse objeto possui propriedades e métodos. Uma de suas propriedades é [selectedIndex], cujo valor é o número da primeira opção selecionada na lista HTML. Se não houver nenhuma opção selecionada, essa propriedade assume o valor -1. Por outro lado, atribuir um valor a essa propriedade equivale a selecionar um novo elemento na lista HTML, e atribuir-lhe o valor -1 equivale a não ter nenhum elemento selecionado. É isso que é feito aqui.
Por fim, observe-se que o código de apresentação [formulaire.aspx] não é acompanhado por um controlador [formulaire.aspx.vb]. De fato, não há nenhuma parte dinâmica gerada pelo servidor no documento HTML; portanto, não há necessidade de um controlador.
5.4.4. Processamento da ação de validação
Quando o controlador processa a ação “validação”, ele deve gerar uma página que liste os valores inseridos pelo usuário. Cabe à página [validation.aspx] realizar essa tarefa. Visualmente, a página se apresenta da seguinte forma:

Seu código HTML é o seguinte:
<%@ Page src="validation.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="validation" %>
<HTML>
<HEAD>
<title>validation</title>
</HEAD>
<body>
<P>Valeurs saisies</P>
<HR width="100%" SIZE="1">
<TABLE id="Table1" cellSpacing="1" cellPadding="1" width="300" border="1">
<TR>
<TD width="84">rdMarie</TD>
<TD><% =rdMarie%></TD>
</TR>
<TR>
<TD width="84">C1</TD>
<TD><%=C1%></TD>
</TR>
<TR>
<TD width="84">C2</TD>
<TD><%=C2%></TD>
</TR>
<TR>
<TD width="84">C3</TD>
<TD><%=C3%></TD>
</TR>
<TR>
<TD width="84">txtSaisie</TD>
<TD><%=txtSaisie%></TD>
</TR>
<TR>
<TD width="84">txtMdp</TD>
<TD><%=txtMdp%></TD>
</TR>
<TR>
<TD width="84">areaSaisie</TD>
<TD><%=areaSaisie%></TD>
</TR>
<TR>
<TD width="84">cmbValeurs</TD>
<TD><%=cmbValeurs%></TD>
</TR>
<TR>
<TD width="84">lstSimple</TD>
<TD><%=lstSimple%></TD>
</TR>
<TR>
<TD width="84">lstMultiple</TD>
<TD><%=lstMultiple%></TD>
</TR>
<TR>
<TD width="84">secret</TD>
<TD><%=secret%></TD>
</TR>
</TABLE>
</body>
</HTML>
As partes dinâmicas <%=variável%> do documento são calculadas pelo controlador [validation.aspx.vb] associado:
Imports System.Text.RegularExpressions
Public Class validation
Inherits System.Web.UI.Page
Protected rdMarie As String
Protected C1 As String
Protected C2 As String
Protected C3 As String
Protected txtSaisie As String
Protected txtMdp As String
Protected areaSaisie As String
Protected cmbValeurs As String
Protected lstSimple As String
Protected lstMultiple As String
Protected secret As String
Protected delimiteur As New Regex("\r\n")
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'recuperam-se os parâmetros enviados
rdMarie = getValue("rdMarie")
C1 = getValue("C1")
C2 = getValue("C2")
C3 = getValue("C3")
txtSaisie = getValue("txtSaisie")
txtMdp = getValue("txtMdp")
areaSaisie = String.Join(",", delimiteur.Split(getValue("areaSaisie")))
cmbValeurs = getValue("cmbValeurs")
lstSimple = getValue("lstSimple")
lstMultiple = getValue("lstMultiple")
secret = getValue("secret")
End Sub
Private Function getValue(ByVal champ As String) As String
' recupera o valor do campo [champ] da solicitação enviada
' alguma coisa?
If Request.Form(champ) Is Nothing Then Return ""
' recupera o(s) valor(es) do campo
Dim valeurs() As String = Request.Form.GetValues(champ)
Dim valeur As String = ""
Dim i As Integer
For i = 0 To valeurs.Length - 1
valeur += "[" + valeurs(i) + "]"
Next
Return valeur
End Function
End Class
O cálculo dos valores a serem exibidos é feito no procedimento [Form_Load]. O valor de um campo “enviado” é obtido pela função getValue(C), em que C é o nome do campo. Os pontos-chave dessa função são os seguintes:
- se C não estiver na cadeia de parâmetros lançada, retorna-se a cadeia vazia como valor de C
- caso contrário, obtém-se a matriz de valores do campo C por meio de [Request.Form.GetValues(C)]. Esses valores são concatenados em uma cadeia de caracteres na forma [val1][val2]...[valn], onde [vali] é o valor nº i do campo C
O campo [areaSaisie] é tratado de maneira especial. Seu valor é enviado pelo navegador na forma areaSaisie=linha1\r\nlinha2\r\n... onde \r é o caractere de código ASCII 13 (retorno de carro) e \n é o caractere de código ASCII 10 (salto de linha). A função getValue(areaSaisie) é, portanto, a sequência “linha1\r\nlinha2\r\n...”. Essa sequência é dividida em linhas pelo método [Regex.Split]. Obtém-se, então, uma matriz de cadeias {linha1,linha2,...}. Essa matriz é transformada na cadeia “linha1,linha2,...” pelo método [String.Join]. É essa última cadeia que será exibida como valor do campo [areaSaisie]. O objetivo aqui era mostrar como se pode obter as diferentes linhas de um campo HTML do tipo [TextArea].
5.4.5. Testes
Colocamos todos os arquivos (global.asax, global.asax.vb, formulaire.aspx, validation.aspx, validation.aspx.vb) em uma pasta <application-path>. Iniciamos o servidor Cassini com os parâmetros (<application-path>,/mvcform1). Criamos na pasta <application-path> um arquivo vazio chamado [default.aspx] e, em seguida, acessamos a URL [http://localhost/mvcform1]. Como [/mvcform1] é o caminho virtual de uma pasta e não de um documento, o servidor web exibirá o documento [default.aspx], caso ele esteja presente. É por isso que criamos esse documento. Antes de exibi-lo, o script [global.asax] será executado e, por fim, fará com que a página [formulaire.aspx] seja exibida. É por isso que o arquivo [default.aspx] pode estar vazio.
Suponhamos que o formulário validado seja o seguinte:

Ao clicar no botão [Envoyer], é exibida a seguinte página:

Observemos, em primeiro lugar, a URL da resposta: [http://localhost/mvcform1/?action=validation]. Trata-se do URL do atributo [action] da tag <form> do formulário [formulaire.aspx]:
<form name="formulaire" method="post" action="?action=validation">
Vamos examinar, um por um, os valores obtidos para os diferentes campos do formulário:
campo | valor | HTML | comentários |
rdMarie | sim | <input type="radio" value="sim" name="rdMarie">Sim <input type="radio" checked value="não" name="rdMarie">Não | o valor obtido é o atributo [value] do botão marcado |
C1 | um | <input type="checkbox" value="um" name="C1">1 | idem |
C2 | dois | <input type="checkbox" marcado value="dois" name="C2">2 | idem |
C3 | <input type="checkbox" value="três" name="C3">3 | esse botão não foi marcado pelo usuário. Portanto, seu valor não foi enviado pelo navegador. No código, a condição [Request.Form("C3") is Nothing] foi, portanto, verdadeira. | |
txtSaisie | Programação asp.net | <input type="text" ... name="txtSaisie"> | o valor obtido é o texto presente no campo de entrada no momento da validação |
txtMdp | mdp | <input type="password" ...name="txtMdp"> | idem |
areaSaisie | noções básicas de programação web | <textarea name="areaSaisie"> ...</textarea> | idem |
cmbValeurs | 3 | <select name="cmbValeurs"> ... <option value="3">opção 3</option> </select> | o valor obtido é o atributo [value] da opção selecionada |
lstSimple | 3 | <select size="3" name="lstSimple"> .... <option value="3">lista3</option> ... </select> | idem |
lstMultiple | 2 4 | <select multiple size="3" name="lstMultiple"> ... <option value="2">multiple2 </option> ... <option value="4">multiple4 </option> ... </select> | os valores obtidos são os dos atributos [value] das opções selecionadas |
secreto | uneValeur | <input type="hidden" name="secret" value="umValor"> | o valor obtido é o atributo [value] do campo oculto |
Agora, vamos nos concentrar nas listas. Suponhamos que, no momento da validação, o estado do formulário seja o seguinte:

- a opção [choix1] está selecionada no comboBox
- nenhuma opção está selecionada nas outras duas listas. Utilizamos os botões [Raz] para obter esse resultado.
Aqui está a página exibida após a validação:

Quando nenhum valor é selecionado em uma lista, o navegador não envia nenhum parâmetro para ela. No código de [validation.aspx.vb], as expressões [Request.Form("lstSimple")] e [Request.Form("lstMultiple")] são, portanto, iguais à constante [Nothing], daí o resultado exibido acima.
5.5. Manter o estado de uma página
5.5.1. Manter o estado de uma página com uma sessão
Duplicamos toda a aplicação anterior em uma nova pasta. Adicionamos um link na página [validation.aspx] que permite ao usuário retornar ao formulário:

A alteração a ser feita na página [validation.aspx] é a adição do link:
.....
<TR>
<TD width="84">secret</TD>
<TD><%=secret%></TD>
</TR>
</TABLE>
<P>
<a href="?action=formulaire">Retour au formulaire</a>
</P>
</body>
</HTML>
O atributo [href] do link tem como valor uma URL parametrizada com o único parâmetro [action=formulaire], permitindo que o servidor saiba que deve exibir o formulário exatamente como estava no momento em que foi validado. Portanto, há uma diferença em relação à ação [init], que exibe um formulário predefinido. A URL parametrizada [?action=formulaire], na verdade, não possui uma URL. Assim, ela será a mesma que permitiu a exibição da página de validação. Se nos lembrarmos do estudo anterior, essa é a URL da pasta do aplicativo. A solicitação passará, portanto, pelo controlador. Este deve agora processar a ação [formulaire]. O código de [global.asax.vb] é modificado da seguinte forma:
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
' recupera-se a ação a ser realizada
Dim action As String
If Request.QueryString("action") Is Nothing Then
action = "init"
Else
action = Request.QueryString("action").ToString.ToLower
End If
' executa-se a ação
Select Case action
Case "init"
Server.Transfer("formulaire.aspx", False)
Case "validation"
Server.Transfer("validation.aspx", True)
Case "formulaire"
Server.Transfer("formulaire.aspx", True)
Case Else
Server.Transfer("formulaire.aspx", True)
End Select
End Sub
No caso em que a ação for “formulário”, basta enviar a solicitação para a página [formulaire.aspx]. Sabemos que essa página exibe um formulário predefinido no qual não há nenhuma parte variável. Portanto, essa página não pode exibir o formulário com os valores que ele possuía no momento em que foi validado. O objetivo aqui é destacar esse ponto. Se todos os arquivos da aplicação tiverem sido colocados em <application-path>, iniciamos o Cassini com os parâmetros (<application-path>,/mvcform2) e, em seguida, acessamos a URL [http://localhost/mvcform2]. Obtemos a seguinte página (visualização parcial):

Preenchemos o formulário da seguinte maneira e, em seguida, o validamos:

Obtemos a seguinte página de confirmação:

Utilizamos o link [Retour au formulaire] presente (mas não exibido) na página acima. Recebemos a seguinte resposta do servidor:

Constatamos que:
- a URL solicitada possui, de fato, o parâmetro action=formulário, conforme desejado
- o formulário exibido perdeu os valores inseridos.
Sabemos por que não encontramos os valores inseridos. Se analisarmos o código do documento [formulaire.aspx], percebemos que tudo é estático e que, por isso, ele é obrigado a exibir sempre a mesma página. Fica claro que precisamos tornar esse código dinâmico. Ele deverá exibir os valores validados pelo usuário. Mas onde armazená-los?
Vamos relembrar a regra de ouro do protocolo sem estado HTTP:
- a URL [http://localhost/mvcform2] é solicitada — uma resposta é recebida. Uma conexão TCP-IP foi aberta entre o cliente e o servidor no início da solicitação e encerrada ao final da resposta.
- O usuário insere e, em seguida, confirma os dados. A URL [http://localhost/mvcform2/?action=validation] é solicitada — uma resposta é recebida. Uma nova conexão TCP-IP foi aberta e, em seguida, encerrada entre os dois parceiros.
- O usuário acessa o link [Retour au formulaire]. A URL [http://localhost/mvcform2/?action=formulaire] é solicitada — uma resposta é recebida. Uma nova conexão TCP-IP foi novamente aberta e, em seguida, encerrada entre os dois parceiros.
Os ciclos de solicitação-resposta são independentes uns dos outros, pois cada um deles utiliza uma nova conexão TCP-IP. Quando um aplicativo cliente-servidor utiliza uma única conexão TCP-IP para uma sequência de trocas, o servidor pode identificar um cliente por meio de sua conexão. Assim, ele pode armazenar informações que associará a uma conexão específica e, dessa forma, acompanhar as trocas. Quando as trocas ocorrem em conexões diferentes, o servidor não consegue identificar um cliente a partir de uma conexão. É necessário outro meio. Apresentamos um deles no capítulo anterior: o mecanismo de sessão. Ele permite que os ciclos de solicitação-resposta armazenem informações em um objeto [Session] acessível a todos os ciclos sucessivos.
Agora que temos um aplicativo MVC com sessão, não podemos mais usar o arquivo [global.asax] como controlador, conforme mostrado no capítulo anterior. A função de controlador de aplicativo deve ser desempenhada por uma página específica dedicada a isso. Neste caso, será a página [main.aspx]. Procederemos da seguinte forma:
- quando o usuário validar seus dados (ação=validação), o controlador [main.aspx.vb] os armazenará na sessão atual antes de exibir a página de validação.
- quando for necessário exibir o formulário com os valores inseridos (ação=formulário), o controlador [main.aspx.vb] os recuperará da sessão e os colocará no contexto antes de exibir o formulário.
5.5.2. O novo controlador de aplicação
O controlador de aplicação é composto pelos dois arquivos [main.aspx, main.aspx.vb]:
[main.aspx]
[main.aspx.vb]
Imports System.Collections.Specialized
Imports Microsoft.VisualBasic
Public Class main
Inherits System.Web.UI.Page
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' recupera-se a ação a ser realizada
Dim action As String
If Request.QueryString("action") Is Nothing Then
action = "init"
Else
action = Request.QueryString("action").ToString.ToLower
End If
' executa-se a ação
Select Case action
Case "init"
' exibe-se o formulário pré-preenchido
Context.Items("formulaire") = initForm()
Server.Transfer("formulaire.aspx", True)
Case "validation"
' exibe-se a página de confirmação após salvar os valores enviados na sessão
Session.Item("formulaire") = Request.Form
Server.Transfer("validation.aspx", True)
Case "formulaire"
' exibe-se o formulário com os valores obtidos da sessão
Context.Items("formulaire") = Session.Item("formulaire")
Server.Transfer("formulaire.aspx", True)
Case Else
' exibe o formulário pré-preenchido
Context.Items("formulaire") = initForm()
Server.Transfer("formulaire.aspx", True)
End Select
End Sub
Private Function initForm() As NameValueCollection
' inicializa-se o formulário
Dim form As New NameValueCollection
form.Set("rdMarie", "non")
form.Set("C2", "deux")
form.Set("txtSaisie", "qqs mots")
form.Set("txtMdp", "ceciestsecret")
form.Set("areasaisie", "ligne1" + ControlChars.CrLf + "ligne2" + ControlChars.CrLf)
form.Set("cmbValeurs", "2")
form.Set("lstSimple", "1")
form.Set("lstMultiple", "1")
form.Add("lstMultiple", "3")
Return form
End Function
End Class
Encontramos aqui a essência da estrutura do controlador de aplicação estudado anteriormente, com as seguintes diferenças:
- o trabalho do controlador é realizado no procedimento [Form_Load]
- no caso da ação [validation], os valores do formulário presentes em [Request.Form] são armazenados na sessão associada à chave “formulário”. Em seguida, a execução é transferida para a página [validation.aspx], que exibirá esses valores.
- Para as demais ações, a execução é transferida, em todos os casos, para a página [formulaire.aspx]. Essa página espera, em seu contexto, uma chave “formulário” que será associada a um objeto do tipo [Request.form], c.a.d ou do tipo [NameValueCollection]. Esse objeto deve conter a coleção dos valores dos campos do formulário.
- No caso de a ação ser [init] ou uma ação não reconhecida, a coleção de valores é construída arbitrariamente pela função [initForm].
- No caso de a ação ser [formulaire], essa coleção é a coleção [Request.Form], que havia sido inserida na sessão pela ação [validation]
5.5.3. O novo formulário
Como o aplicativo não exibe mais o mesmo conteúdo no formulário, este deve ser gerado dinamicamente. A nova página [formulaire.aspx] fica da seguinte forma:
<%@ Page src="formulaire.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="formulaire" %>
<HTML>
<HEAD>
<title>Formulaire</title>
<script language="javascript">
function effacer(){
alert("Vous avez cliqué sur le bouton [Effacer]");
}
function raz(liste){
liste.selectedIndex=-1
}
</script>
</HEAD>
<body>
<p>
Gestion d'un formulaire
</p>
<hr>
<form name="formulaire" method="post" action="main.aspx?action=validation">
<table border="1">
<tr>
<td>
Etes-vous marié(e)</td>
<td>
<p align="center">
<INPUT type="radio" value="oui" name="rdMarie" <%=rdouichecked%>>Oui
<INPUT type="radio" value="non" name="rdMarie" <%=rdnonchecked%>>Non
</p>
</td>
</tr>
<TR>
<TD>Cases à cocher
</TD>
<TD>
<P align="center">
<INPUT type="checkbox" value="un" name="C1" <%=c1checked%>>1
<INPUT type="checkbox" value="deux" name="C2" <%=c2checked%>>2
<INPUT type="checkbox" value="trois" name="C3" <%=c3checked%>>3
</P>
</TD>
</TR>
<TR>
<TD>Champ de saisie</TD>
<TD>
<P align="center">
<INPUT type="text" maxLength="30" value="<%=txtSaisie%>" name="txtSaisie">
</P>
</TD>
</TR>
<tr>
<td>
Mot de passe</td>
<td>
<p align="center">
<input type="password" maxlength="12" size="12" value="<%=txtMdp%>" name="txtMdp">
</p>
</td>
</tr>
<tr>
<td>
Boîte de saisie</td>
<td>
<textarea name="areaSaisie"><%=areaSaisie%></textarea>
</td>
</tr>
<tr>
<td>
ComboBox</td>
<td>
<select name="cmbValeurs">
<%=cmbValeursOptions%>
</select>
</td>
</tr>
<tr>
<td>
Liste à choix simple</td>
<td>
<select size="3" name="lstSimple">
<%=lstSimpleOptions%>
</select>
<INPUT type="button" value="Raz" name="btnRazSimple" onclick="raz(lstSimple)">
</td>
</tr>
<tr>
<td>
Liste à choix multiple</td>
<td>
<select multiple size="3" name="lstMultiple">
<%=lstMultipleOptions%>
</select>
<INPUT type="button" value="Raz" name="btnRazMultiple" onclick="raz(lstMultiple)">
</td>
</tr>
<tr>
<td>
Bouton simple</td>
<td>
<p align="center">
<input onclick="effacer()" type="button" value="Effacer" name="btnEffacer">
</p>
</td>
</tr>
<tr>
<td>
Bouton submit</td>
<td>
<p align="center">
<input type="submit" value="Envoyer" name="btnEnvoyer">
</p>
</td>
</tr>
<tr>
<td>
Bouton reset</td>
<td>
<p align="center">
<input type="reset" value="Rétablir" name="btnRetablir" runat="server">
</p>
</td>
</tr>
</table>
<input type="hidden" name="secret" value="uneValeur">
</form>
</body>
</HTML>
Vamos comentar as variáveis dinâmicas que aparecem no código HTML:
variável | função |
terá o valor “checked” se o botão de opção [oui] precisar ser marcado; caso contrário, terá o valor “” | |
o mesmo vale para o botão de opção [non] | |
o mesmo vale para a caixa de seleção [C1] | |
o mesmo vale para a caixa de seleção [C2] | |
o mesmo vale para a caixa de seleção [C3] | |
o texto a ser inserido no campo [txtSaisie] | |
o texto a ser inserido no campo [txtMdp] | |
o texto a ser inserido no campo [areaSaisie] | |
o texto HTML das opções da lista suspensa [cmbValeurs] | |
o texto HTML das opções da lista de seleção [lstSimple] | |
o texto HTML das opções da lista suspensa [lstMultiple] | |
Os valores dessas variáveis são calculados pelo controlador da página [formulaire.aspx.vb]:
Imports Microsoft.VisualBasic
Imports System.Collections.Specialized
Public Class formulaire
Inherits System.Web.UI.Page
' campos fixos do formulário
Private libellésCmbValeurs() As String = {"choix1", "choix2", "choix3"}
Private valeursCmbValeurs() As String = {"1", "2", "3"}
Private libellésLstSimple() As String = {"liste1", "liste2", "liste3"}
Private valeursLstSimple() As String = {"1", "2", "3"}
Private libellésLstMultiple() As String = {"multiple1", "multiple2", "multiple3", "multiple4", "multiple5"}
Private valeursLstMultiple() As String = {"1", "2", "3", "4", "5"}
' campos dinâmicos do formulário
Protected rdouichecked As String
Protected rdnonchecked As String
Protected c1checked As String
Protected c2checked As String
Protected c3checked As String
Protected txtSaisie As String
Protected txtMdp As String
Protected areaSaisie As String
Protected cmbValeursOptions As String
Protected lstSimpleOptions As String
Protected lstMultipleOptions As String
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' recupera-se a solicitação anterior na sessão
Dim form As NameValueCollection
If Not Context.Items("formulaire") Is Nothing Then
form = Context.Items("formulaire")
Else
form = New NameValueCollection
End If
' prepara-se a página a ser exibida
' botões de opção
rdouichecked = ""
rdnonchecked = "checked"
If isEqual(form("rdMarie"), "oui") Then
rdouichecked = "checked"
rdnonchecked = ""
End If
' caixas de seleção
c1checked = ""
If isEqual(form("C1"), "un") Then c1checked = "checked"
c2checked = ""
If isEqual(form("C2"), "deux") Then c2checked = "checked"
c3checked = ""
If isEqual(form("C3"), "trois") Then c3checked = "checked"
' campos de preenchimento
txtSaisie = ""
If Not form("txtSaisie") Is Nothing Then txtSaisie = form("txtSaisie").ToString
txtMdp = ""
If Not form("txtMdp") Is Nothing Then txtMdp = form("txtMdp").ToString
areaSaisie = ""
If Not form("areaSaisie") Is Nothing Then areaSaisie = form("areaSaisie").ToString
' listas
Dim sélections() As String = {}
If Not form("cmbValeurs") Is Nothing Then sélections = form.GetValues("cmbValeurs")
cmbValeursOptions = getOptions(valeursCmbValeurs, libellésCmbValeurs, sélections)
sélections = New String() {}
If Not form("lstSimple") Is Nothing Then sélections = form.GetValues("lstSimple")
lstSimpleOptions = getOptions(valeursLstSimple, libellésLstSimple, sélections)
sélections = New String() {}
If Not form("lstMultiple") Is Nothing Then sélections = form.GetValues("lstMultiple")
lstMultipleOptions = getOptions(valeursLstMultiple, libellésLstMultiple, sélections)
End Sub
Private Function getOptions(ByRef valeurs() As String, ByRef libelles() As String, ByRef sélections() As String) As String
' gera o código HTML das opções de uma tag <select>
' valores: tabela de valores das opções da tag
' rótulos: tabela dos rótulos das opções da tag
' seleções: opções a serem selecionadas
Dim iValeur As Integer
Dim iSelection As Integer
Dim selected As String
Dim toString As String = ""
' percorre-se a lista de valores das opções
For iValeur = 0 To valeurs.Length - 1
' verifica-se se o valor atual deve ser selecionado
selected = "" : iSelection = 0
Do While iSelection < sélections.Length And selected = ""
If valeurs(iValeur) = sélections(iSelection) Then selected = "selected"
iSelection += 1
Loop
' insere-se o código HTML da opção
toString += "<option " + selected + " value='" + valeurs(iValeur) + "'> " _
+ libelles(iValeur) + "</option>" + ControlChars.CrLf
Next
' retorna o resultado
Return toString
End Function
Private Function isEqual(Byval champ As Object, ByVal valeur As String) As Boolean
' retorna verdadeiro se o campo for igual ao valor
If champ Is Nothing OrElse champ.ToString <> valeur Then
Return false
Else
Return true
End If
end function
End Class
Quando a página [formulaire.aspx] começa a ser executada, ela encontra em seu contexto uma chave “formulário” associada ao conjunto de valores dos campos que deve exibir.
' recupera-se a consulta anterior na sessão
Dim form As NameValueCollection
If Not Context.Items("formulaire") Is Nothing Then
form = Context.Items("formulaire")
Else
form = New NameValueCollection
End If
Pode-se questionar por que se verifica se [Context.Items("formulaire")] existe. De fato, o controlador atribui um valor a esse objeto em todos os casos. No entanto, nada impede que o cliente solicite diretamente a página [formulaire.aspx] sem passar pelo controlador. Se isso ocorrer, o código anterior funcionará com uma coleção de valores vazia, mas não haverá “falha”.
O código explora a coleção de valores que recebeu para calcular todas as variáveis dinâmicas da página HTML a ela associada. Embora seja extenso, esse código não é especialmente complicado, e deixamos que o leitor se aprofunde nele para não sobrecarregar esta explicação. No entanto, vamos nos deter na maneira de gerar o código HTML a partir das três listas do tipo [select]. Esse código é gerado pela seguinte função:
Private Function getOptions(ByRef valeurs() As String, ByRef libelles() As String, ByRef sélections() As String) As String
' retorna o código HTML das opções de uma tag <select>
' valores: tabela dos valores das opções da tag
' rótulos: tabela dos rótulos das opções da tag
' seleções: opções a serem selecionadas
Dim iValeur As Integer
Dim iSelection As Integer
Dim selected As String
Dim toString As String = ""
' percorre-se a lista de valores das opções
For iValeur = 0 To valeurs.Length - 1
' verifica-se se o valor atual deve ser selecionado
selected = "" : iSelection = 0
Do While iSelection < sélections.Length And selected = ""
If valeurs(iValeur) = sélections(iSelection) Then selected = "selected"
iSelection += 1
Loop
' insere-se o código HTML da opção
toString += "<option " + selected + " value='" + valeurs(iValeur) + "'> " _
+ libelles(iValeur) + "</option>" + ControlChars.CrLf
Next
' retorna-se o resultado
Return toString
End Function
Vale lembrar que as opções de uma tag <select> correspondem ao código HTML a seguir:
Para cada opção, há, portanto, três informações a serem geradas:
- o valor da opção no atributo [value]
- o texto da opção entre as tags <option> e </option>
- a palavra-chave [selected], caso a opção deva ser selecionada na lista
Para gerar essas três informações para cada uma das opções, a função [getOptions] recebe três valores:
- a tabela de valores das opções em [valeurs]
- a tabela de textos das opções em [libelles]
- a tabela de valores a serem selecionados em [sélections]
5.5.4. A página de validação
A página de validação permanece inalterada:
[validation.aspx]
<%@ Page src="validation.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="validation" %>
<HTML>
<HEAD>
<title>validation</title>
</HEAD>
<body>
<P>Valeurs saisies</P>
<HR width="100%" SIZE="1">
<TABLE id="Table1" cellSpacing="1" cellPadding="1" width="300" border="1">
<TR>
<TD width="84">rdMarie</TD>
<TD><% =rdMarie%></TD>
</TR>
<TR>
<TD width="84">C1</TD>
<TD><%=C1%></TD>
</TR>
<TR>
<TD width="84">C2</TD>
<TD><%=C2%></TD>
</TR>
<TR>
<TD width="84">C3</TD>
<TD><%=C3%></TD>
</TR>
<TR>
<TD width="84">txtSaisie</TD>
<TD><%=txtSaisie%></TD>
</TR>
<TR>
<TD width="84">txtMdp</TD>
<TD><%=txtMdp%></TD>
</TR>
<TR>
<TD width="84">areaSaisie</TD>
<TD><%=areaSaisie%></TD>
</TR>
<TR>
<TD width="84">cmbValeurs</TD>
<TD><%=cmbValeurs%></TD>
</TR>
<TR>
<TD width="84">lstSimple</TD>
<TD><%=lstSimple%></TD>
</TR>
<TR>
<TD width="84">lstMultiple</TD>
<TD><%=lstMultiple%></TD>
</TR>
<TR>
<TD width="84">secret</TD>
<TD><%=secret%></TD>
</TR>
</TABLE>
<P>
<a href="main.aspx?action=formulaire">Retour au formulaire</a>
</P>
</body>
</HTML>
[validation.aspx.vb]
Imports Microsoft.VisualBasic
Imports System.Text.RegularExpressions
Public Class validation
Inherits System.Web.UI.Page
Protected rdMarie As String
Protected C1 As String
Protected C2 As String
Protected C3 As String
Protected txtSaisie As String
Protected txtMdp As String
Protected areaSaisie As String
Protected cmbValeurs As String
Protected lstSimple As String
Protected lstMultiple As String
Protected secret As String
Protected delimiteur As New Regex("\r\n")
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'recuperam-se os parâmetros enviados
rdMarie = getValue("rdMarie")
C1 = getValue("C1")
C2 = getValue("C2")
C3 = getValue("C3")
txtSaisie = getValue("txtSaisie")
txtMdp = getValue("txtMdp")
areaSaisie = String.Join(",", delimiteur.Split(getValue("areaSaisie")))
cmbValeurs = getValue("cmbValeurs")
lstSimple = getValue("lstSimple")
lstMultiple = getValue("lstMultiple")
secret = getValue("secret")
' eles são salvos na sessão
'Session("formulário") = Request.Form
End Sub
Private Function getValue(ByVal champ As String) As String
' recupera o valor do campo [champ] da solicitação enviada
' o que é isso?
If Request.Form(champ) Is Nothing Then Return ""
' recupera o(s) valor(es) do campo
Dim valeurs() As String = Request.Form.GetValues(champ)
Dim valeur As String = ""
Dim i As Integer
For i = 0 To valeurs.Length - 1
valeur += "[" + valeurs(i) + "]"
Next
Return valeur
End Function
End Class
5.5.5. Os testes
Os arquivos [main.aspx, main.aspx.vb,formulaire.aspx,formulaire.aspx.vb, validation.aspx, validation.aspx.vb] são colocados em <application-path> e o Casini é iniciado com os parâmetros (<application-path>,/mvcform3). Em seguida, acessamos a URL [http://localhost/mvcform3/main.aspx]. Obtemos o formulário pré-inicializado:

Preenchemos o formulário da seguinte maneira:

Utilizamos o botão [Envoyer] acima. Recebemos a seguinte resposta do servidor:

Usamos o link [Retour au formulaire] acima para voltar ao formulário. Recebemos a seguinte resposta:

Encontramos, de fato, o formulário exatamente como o enviamos.
5.5.6. Conclusão
O exemplo anterior nos mostrou que é possível manter o estado de uma página ao longo dos ciclos de solicitação-resposta entre o cliente e o servidor. No entanto, esse trabalho não é trivial. Veremos em um capítulo posterior que, com ASP.NET, é possível deixar que o servidor restabeleça por conta própria o estado de uma página.



