5. Gestione dell’interfaccia utente
5.1. Introduction
Nella relazione client-server del web, il client trasmette informazioni al server sotto forma di stringa di parametri [param1=val1¶m2=val2&...]. Nei nostri esempi precedenti, abbiamo costruito questa stringa il più delle volte manualmente, richiedendo URL della forma [http://localhost/appli? param1=val1¶m2=val2&...]. In realtà, le informazioni che il client trasmette al server provengono dai moduli compilati dall’utente. In questo capitolo esploreremo la loro creazione. Introdurremo inoltre lo strumento WebMatrix che ci consentirà di progettare le interfacce utente. L’installazione di questo strumento è descritta negli allegati.
5.2. Il linguaggio HTML
5.2.1. Un esempio
Consideriamo il seguente esempio, creato con [Web Matrix], che presenta:
- una tabella
- un'immagine
- un link

Eseguiamo [WebMatrix] e poi selezioniamo l'opzione [File/New File]:

Scegliamo di creare una pagina HTML. Le informazioni sopra riportate creeranno un file [d:\data\devel\aspnet\chap4\exemple1\exemple1.htm]. [WebMatrix] offre due possibilità per modificare questo file: la modalità [Design] e la modalità [HTML]:

La modalità [Design] consente di utilizzare la tavolozza dei componenti HTML offerta da [WebMatrix]:

Per inserire un elemento di questa tavolozza, è sufficiente fare doppio clic su di esso e poi posizionarlo nella finestra [Design]. La modalità [HTML] consente di creare il documento HTML utilizzando un editor di testo. A tal fine è necessario conoscere la sintassi del linguaggio HTML. Nella scheda [HTML] è stato generato uno scheletro di documento:

La finestra [HTML] è molto utile per chi non conosce il linguaggio HTML. L'utente crea il proprio documento nella finestra [Design] e verifica il codice HTML generato nella finestra [HTML]. In questo modo acquisisce progressivamente padronanza di HTML e può abbastanza rapidamente lavorare esclusivamente con l’editor di testo senza l’ausilio della modalità [Design]. Mostreremo ora come costruire il documento HTML presentato all’inizio di questa sezione. Lavoriamo nella finestra [Design]. Innanzitutto, inseriamo direttamente la prima riga di testo:

- aggiungiamo il componente [Horizontal Rule] nella tavolozza dei componenti:

- aggiungiamo il componente [Table]:

- posizioniamo il cursore sulla terza riga della tabella per eliminarla con l'opzione [HTML/Edit Table/Delete Table Row]. Quindi inseriamo il testo desiderato in ogni cella:

- posizioniamo il cursore in una delle celle della tabella e ne esaminiamo le proprietà. La finestra delle proprietà è visualizzata in basso a destra nell’area di lavoro:

- la cella è rappresentata dal tag HTML <TD>. Ci vengono quindi mostrate le proprietà del tag <TD>. Ci concentriamo sulla tabella, che è un oggetto che racchiude la cella. Facciamo clic sull'elenco a discesa (click to see parent HTML elements) qui sopra per selezionare l'oggetto <TABLE>:

- L’oggetto <TABLE> ha una proprietà [border] che definisce la larghezza del bordo che circonda le celle della tabella. In questo caso, impostiamo border=1.

- Modifichiamo ora gli attributi dell’oggetto <TD> della cella (1,2) per impostare align=Center e width=200 (pixel). Il testo sarà centrato nella cella (align=center) e questa avrà una larghezza di 200 pixel. Per visualizzare la modifica, a volte potrebbe essere necessario selezionare la scheda [HTML] e poi tornare alla scheda [Design]:

- ora inseriamo il testo che precede l’immagine:

- poi l’immagine facendo doppio clic sul componente [image] dalla tavolozza:

- selezioniamo l'immagine per modificarne le proprietà:

- nell’attributo [src], inseriamo il nome del file contenente l’immagine, in questo caso [univ01.gif]:

- inseriamo il testo che precede il link:

- trasformiamo il testo [ici] in un link all'URL [http://istia.univ-angers.fr]. Per farlo, lo selezioniamo e poi scegliamo l'opzione [HTML/Insert Hyperlink]:

- otteniamo il seguente risultato:

- ci siamo quasi. Diamo un’occhiata al codice HTML generato nella scheda [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>
Ci restano ancora alcuni dettagli da sistemare. Innanzitutto vorremmo assegnare un titolo al nostro documento. [WebMatrix] non consente di farlo in modalità [Design]. Nella scheda [HTML] sostituiamo la sequenza <head>..</head> con la seguente sequenza:
Inoltre, vorremmo che il testo [Le langage HTML - 1] fosse visualizzato con caratteri più grandi. La sequenza <Hi>testo</Hi> consente di impostare la dimensione di un testo con i che varia da 1 a 6, dal più grande al più piccolo. In questo caso, sceglieremo H2. La sequenza
diventa:
La finestra [Design] riflette le nostre modifiche:

Non ci resta che eseguire il test utilizzando l'opzione [View/Start] o [F5]. L'opzione [WebMatrix] richiede alcune informazioni per avviare il server Web [Cassini]:

Possiamo accettare i valori predefiniti. Il server [Cassini] viene avviato e la nostra pagina viene visualizzata in un browser:

Per curiosità, possiamo verificare con quali parametri è stato avviato [Cassini]:

Abbiamo illustrato le basi per la creazione di una pagina HTML con [WebMatrix]. Il lettore è invitato a creare altre pagine HTML e a verificare ogni volta il codice HTML generato. A poco a poco, sarà in grado di creare una pagina senza l’ausilio della modalità [Design]. Un documento HTML ha la seguente struttura generale:
L'intero documento è racchiuso tra i tag <html>...</html>. È composto da due parti:
<head>...</head>: è la parte non visibile del documento. Fornisce informazioni al browser che visualizzerà il documento. Spesso vi si trova il tag <title>...</title>, che definisce il testo che verrà visualizzato nella barra del titolo del browser. Vi si possono trovare anche altri tag, in particolare quelli che definiscono le parole chiave del documento, parole chiave che verranno poi utilizzate dai motori di ricerca. In questa parte si possono trovare anche degli script, scritti per lo più in JavaScript o VBScript, che verranno eseguiti dal browser.
<body attributi>...</body>: è la parte che verrà visualizzata dal browser. I tag HTML contenuti in questa sezione indicano al browser l’aspetto visivo “desiderato” per il documento. Ogni browser interpreterà questi tag a modo suo. Due browser possono quindi visualizzare in modo diverso lo stesso documento web. Questo rappresenta generalmente uno dei grattacapi dei web designer.
Il codice HTML del documento precedente era il seguente:
<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 | tag ed esempi HTML |
<title>HTML1</title> HTML1 apparirà nella barra del titolo del browser che visualizzerà il documento | |
<hr>: visualizza una linea orizzontale | |
<attributi tabella>....</table>: per definire la tabella <tr attributi>...</tr>: per definire una riga <td attributi>...</td>: per definire una cella esempi: <table border="1">...</table>: l'attributo border definisce lo spessore del bordo della tabella <td align="center" width="200">cella(1,2)</td>: definisce una cella il cui contenuto sarà cellule(1,2). Questo contenuto sarà centrato orizzontalmente (align="center"). La cella avrà una larghezza di 200 pixel (width="200") | |
<img src="univ01.gif" />: definisce un'immagine il cui file sorgente è univ01.gif sul server web (src="univ01.gif"). Questo link si trova in un documento web generato con URL http://localhost/exemple1.htm. Pertanto, il browser richiederà l'URL http://localhost/univ01.gif per ottenere l'immagine qui referenziata. | |
<a href="http://istia.univ-angers.fr">qui</a>: fa sì che il testo ici funga da link verso l'URL http://istia.univ-angers.fr. |
Da questo semplice esempio si evince che, per costruire l’intero documento, il browser deve effettuare due richieste al server:
http://localhost/exemple1.htm per ottenere il codice sorgente HTML del documento
http://localhost/univ01.gif per ottenere l'immagine univ01.gif
5.2.2. Creazione di un modulo
Un modulo HTML ha lo scopo di presentare all'utente una pagina di inserimento dati simile ai moduli di inserimento presenti in Windows. Il modulo di inserimento viene inviato al browser sotto forma di documento HTML. Quest’ultimo mostrerà il modulo all’utente, che lo compilerà e lo convaliderà tramite un pulsante dedicato. Il browser trasmetterà quindi i valori inseriti al server per l’elaborazione. Si noterà che non viene inviato al server l’intero modulo, ma solo i valori inseriti. L’esempio seguente presenta un modulo Web creato anch’esso con WebMatrix:

Il codice HTML generato da [WebMatrix] è il seguente:
<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>
L'associazione tra controllo visivo <--> tag HTML è la seguente:
Controllo | tag HTML |
<form name="modulo" method="post"> | |
<input type="text" maxlength="30" value="alcune parole" name="txtSaisie" /> | |
<input type="password" maxlength="12" size="12" value="unMotDePasse" name="txtMdp" /> | |
<textarea name="areaSaisie">riga1 riga2</textarea> | |
<input type="radio" value="sì" name="rdMarie" />Sì <input type="radio" checked value="no" name="rdMarie" />No | |
<input type="checkbox" value="uno" name="C1" />1 <input type="checkbox" checked value="due" name="C2" />2 <input type="checkbox" value="tre" name="C3" />3 | |
<select name="cmbValeurs"> <option value="1">scelta1</option> <option value="2" selected>opzione2</option> <option value="3">scelta3</option> </select> | |
<select size="3" name="lstSimple"> <option value="1" selected>elenco1</option> <option value="2">elenco2</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>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="hidden" name="secret" value="uneValeur" /> | |
<input type="submit" value="Invia" name="btnEnvoyer" /> | |
<input type="reset" value="Ripristina" name="btnRetablir" runat="server" /> | |
<input onclick="effacer()" type="button" value="Cancella" name="btnEffacer" /> |
Esaminiamo questi diversi controlli.
5.2.2.1. Il modulo
<form name="modulo" method="post"> |
<form name="..." method="..." action="...">...</form> | |
name="frmexemple": nome del modulo method="..." : metodo utilizzato dal browser per inviare al server web i valori raccolti nel modulo action="..." : URL a cui verranno inviati i valori raccolti nel modulo. Un modulo web è racchiuso tra i tag <form>...</form>. Il modulo può avere un nome (name="xx"). Questo vale per tutti i controlli presenti in un modulo. Tale nome è utile se il documento web contiene script che devono fare riferimento agli elementi del modulo. Lo scopo di un modulo è quello di raccogliere le informazioni fornite dall’utente tramite tastiera o mouse e di inviarle a una pagina web del server. Quale? Quella indicata nell’attributo action="URL". Se questo attributo è assente, le informazioni verranno inviate al server del documento in cui si trova il modulo. In che modo un client web trasmette le informazioni (quelle contenute nel modulo) a un server web? Lo abbiamo visto in dettaglio. Può utilizzare due metodi diversi denominati POST e GET. L’attributo method="méthode", con il metodo impostato su GET o POST, del tag <form> indica al browser il metodo da utilizzare per inviare le informazioni raccolte nel modulo all'URL specificato dall'attributo action="URL". Quando l'attributo method non è specificato, viene utilizzato per impostazione predefinita il metodo GET. |
5.2.2.2. Campo di immissione

<input type="text" maxlength="30" value="alcune parole" name="txtSaisie" /> <input type="password" maxlength="12" size="12" value="unMotDePasse" name="txtMdp" /> |
<input type="..." name="..." size=".." value=".."> Il tag input è disponibile per diversi controlli. È l'attributo type che permette di distinguere questi diversi controlli tra loro. | |
type="text": specifica che si tratta di un campo di immissione type="password": i caratteri presenti nel campo di immissione vengono sostituiti da asterischi (*). È l'unica differenza rispetto al campo di immissione normale. Questo tipo di controllo è adatto per l'immissione delle password. size="12": numero di caratteri visibili nel campo - non impedisce l'inserimento di un numero maggiore di caratteri maxlength="30": imposta a 30 il numero massimo di caratteri; spetta al browser garantire il rispetto di questo attributo name="txtSaisie": nome del controllo value="alcune parole": testo che verrà visualizzato nel campo di immissione. |
5.2.2.3. Campo di immissione multilinea

<textarea name="areaSaisie">riga1 riga2</textarea> |
<textarea ...>testo</textarea> visualizza un campo di immissione multilinea con del testo precompilato | |
rows="2": numero di righe cols="'20" : numero di colonne name="areaSaisie": nome del controllo |
5.2.2.4. Pulsanti di opzione
![]()
<input type="radio" value="sì" name="rdMarie" />Sì <input type="radio" checked value="no" name="rdMarie" />No |
<input type="radio" attributo2="valore2" ..../>testo visualizza un pulsante di opzione con del testo accanto. | |
name="rdMarie": nome del controllo. I pulsanti di opzione con lo stesso nome formano un gruppo di pulsanti mutuamente esclusivi: è possibile selezionare solo uno di essi. value="valore": valore assegnato al pulsante di opzione. Non bisogna confondere questo valore con il testo visualizzato accanto al pulsante di opzione, che serve solo a scopo di visualizzazione. checked: se questa parola chiave è presente, il pulsante di opzione è selezionato, altrimenti non lo è. |
5.2.2.5. Caselle di controllo
<input type="checkbox" value="uno" name="C1" />1 <input type="checkbox" checked value="due" name="C2" />2 <input type="checkbox" value="tre" name="C3" />3 |
![]()
<input type="checkbox" attributo2="valore2" ..../>testo visualizza una casella di controllo con del testo accanto. | |
name="C1": nome del controllo. Le caselle di controllo possono avere o meno lo stesso nome. Le caselle con lo stesso nome formano un gruppo di caselle associate. value="valore": valore assegnato alla casella di controllo. Non bisogna confondere questo valore con il testo visualizzato accanto al pulsante di opzione. Quest'ultimo è destinato esclusivamente alla visualizzazione. checked: se questa parola chiave è presente, il pulsante di opzione è selezionato, altrimenti non lo è. |
5.2.2.6. Elenco a discesa (combo)
<select name="cmbValeurs"> <option value="1">scelta1</option> <option value="2" selected>scelta2</option> <option value="3">opzione 3</option> </select> |
![]()
<select size=".." name=".."> <option [selected="selected"] [value="valeur"]>testo</option> ... </select> visualizza in un elenco i testi compresi tra i tag <option>...</option> | |
name="cmbValeurs": nome del controllo. size="1": numero di elementi visibili nell'elenco. size="1" rende l'elenco equivalente a una casella combinata. È il valore predefinito se l'attributo [size] è assente. selected="selected": se questo attributo è presente per un elemento dell'elenco, quest'ultimo appare selezionato nell'elenco. Nel nostro esempio sopra riportato, l'elemento dell'elenco choix2 appare come elemento selezionato nel menu a tendina quando questo viene visualizzato per la prima volta. value="valore": imposta il valore da inviare al server se l'elemento viene selezionato. Se questo attributo è assente, al server viene inviato il testo associato all'opzione. |
5.2.2.7. Elenco a selezione singola
<select size="3" name="lstSimple"> <option value="1" selected>lista1</option> <option value="2">lista2</option> <option value="3">elenco3</option> <option value="4">lista4</option> <option value="5">elenco5</option> </select> |

<select size=".." name=".."> <option [selected] [value="valeur"]>...</option> ... </select> visualizza in un elenco i testi compresi tra i tag <option>...</option> | |
gli stessi utilizzati per l'elenco a discesa che visualizza un solo elemento. Questo controllo differisce dall'elenco a discesa precedente solo per l'attributo size>1. |
5.2.2.8. Elenco a selezione multipla
<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> visualizza in un elenco i testi compresi tra i tag <option>...</option> | |
multiple: consente la selezione di più elementi nell'elenco. Nell'esempio sopra riportato, gli elementi liste1 e liste3 sono entrambi selezionati. |
5.2.2.9. Pulsante di tipo button
<input onclick="effacer()" type="button" value="Cancella" name="btnEffacer" /> |
![]()
<input type="button" value="..." name="..." onclick="effacer()" ....> | |
type="button": definisce un controllo pulsante. Esistono altri due tipi di pulsante: submit e reset. value="Cancella": il testo visualizzato sul pulsante onclick="funzione()": consente di definire una funzione da eseguire quando l'utente fa clic sul pulsante. Questa funzione fa parte degli script definiti nel documento web visualizzato. La sintassi precedente è una sintassi javascript. Se gli script sono scritti in VBScript, occorre scrivere onclick="funzione" senza le parentesi. La sintassi rimane identica se è necessario passare dei parametri alla funzione: onclick="funzione(val1, val2,...)" Nel nostro esempio, un clic sul pulsante Effacer richiama la seguente funzione JavaScript effacer: La funzione effacer visualizza un messaggio: ![]() |
5.2.2.10. Pulsante di tipo «submit»
<input type="submit" value="Invia" name="btnEnvoyer" /> |
![]()
<input type="submit" value="Invia" name="btnEnvoyer"> | |
type="submit": definisce il pulsante come pulsante di invio dei dati del modulo al server web. Quando l'utente clicca su questo pulsante, il browser invia i dati del modulo all'URL URL definito nell'attributo action del tag <form> secondo il metodo definito dall'attributo method dello stesso tag. value="Invia": il testo visualizzato sul pulsante |
5.2.2.11. Pulsante di tipo reset
<input type="reset" value="Ripristina" name="btnRetablir" runat="server" /> |
![]()
<input type="reset" value="Ripristina" name=" btnRetablir "> | |
type="reset": definisce il pulsante come pulsante di ripristino del modulo. Quando l'utente fa clic su questo pulsante, il browser riporta il modulo allo stato in cui lo ha ricevuto. value="Ripristina": il testo visualizzato sul pulsante |
5.2.2.12. Campo nascosto
<input type="hidden" name="secret" value="uneValeur" /> |
<input type="hidden" name="..." value="..."> | |
type="hidden": specifica che si tratta di un campo nascosto. Un campo nascosto fa parte del modulo ma non viene mostrato all'utente. Tuttavia, se l'utente richiedesse al proprio browser di visualizzare il codice sorgente, vedrebbe la presenza del tag <input type="hidden" value="..."> e quindi il valore del campo nascosto. value="unValore": valore del campo nascosto. A cosa serve il campo nascosto? Può consentire al server web di conservare informazioni nel corso delle richieste di un cliente. Consideriamo un'applicazione per gli acquisti online. Il cliente acquista un primo articolo art1 in quantità q1 su una prima pagina di un catalogo, quindi passa a una nuova pagina del catalogo. Per ricordare che il cliente ha acquistato q1 articoli art1, il server può inserire queste due informazioni in un campo nascosto del modulo web della nuova pagina. In questa nuova pagina, il cliente acquista gli articoli q2 e art2. Quando i dati di questo secondo modulo verranno inviati al server (submit), quest’ultimo riceverà non solo le informazioni (q2,art2), ma anche (q1,art1), che fa anch’esse parte del modulo come campi nascosti non modificabili dall’utente. Il server web inserirà quindi in un nuovo campo nascosto le informazioni (q1,art1) e (q2,art2) e invierà una nuova pagina del catalogo. E così via. |
5.3. Invio dei valori di un modulo da un browser a un server web
Sappiamo già, grazie al capitolo precedente, come un client invia informazioni al server. Lo fa tramite:
- una richiesta HTTP GET url?param1=va1¶m2=val2&....
- una richiesta HTT POST url seguita da un documento contenente la stringa di parametri param1=va1¶m2=val2&....
Il browser utilizzerà uno di questi due metodi a seconda che l’attributo [method] del tag [form] sia GET o POST. È proprio ciò che mostreremo ora. La pagina esaminata in precedenza è una pagina statica. Per poter accedere alle intestazioni HTTP inviate dal browser che richiederà questo documento, la trasformiamo in una pagina dinamica per un server web .NET (IIS o Cassini). Il codice statico precedente viene inserito in un file [formulaire_get.aspx] e il suo contenuto è il seguente:
<%@ 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>
La pagina di presentazione sopra riportata è associata al controller [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 la richiesta corrente in request.txt nella cartella della pagina
Dim requestFileName As String = Me.MapPath(Me.TemplateSourceDirectory) + "\request.txt"
Me.Request.SaveAs(requestFileName, True)
End Sub
End Class
Ad ogni richiamo del documento [formulaire_get.aspx], la richiesta del cliente verrà salvata in un file [request.txt] tramite la procedura Page_Init. Abbiamo già incontrato questa modalità di funzionamento, pertanto non forniremo ulteriori commenti sul controller.
5.3.1. Metodo GET
Effettuiamo un primo test: nel codice HTML del documento, il tag FORM è definito come segue:
<form name="formulaire" method="get">
Inseriamo i file [formulaire_get.aspx] e [formulaire_get.aspx.vb] in una cartella <application-path> e avviamo il server Cassini con i parametri (<application-path>,/form2). Richiediamo l'URL http://localhost/form2/formulaire_get.aspx:

Il browser ha appena effettuato una richiesta e sappiamo che questa è stata salvata nel file [request.txt]. Diamo un’occhiata al suo contenuto:
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
Il browser ha utilizzato una richiesta HTTP GET per richiedere l'URL [http://localhost/form2/formulaire_get.aspx]. Questo accade sempre quando l'URL viene fornito dall'utente. Il modulo viene compilato nel modo seguente:

Utilizziamo il pulsante [Envoyer] sopra indicato. Il suo codice HTML è il seguente:
All'attivazione di un pulsante di tipo [Submit], il browser invia i parametri del modulo (tag <form>) all'URL indicato nell'attributo [action] del tag <form action="URL">, se presente. Se tale attributo non esiste, i parametri del modulo vengono inviati all'URL che ha generato il modulo. È questo il caso in questione. Il pulsante [Envoyer] dovrebbe quindi generare una richiesta del browser all’URL [http://localhost/form2/formulaire_get.aspx] con il trasferimento dei parametri del modulo. Poiché la pagina [formulaire_get.aspx] memorizza la richiesta ricevuta, dovremmo essere in grado di capire come il client abbia trasferito tali parametri. Proviamo. Facciamo clic sul pulsante [Envoyer]. Riceviamo la seguente risposta dal browser:

Si tratta della pagina iniziale, ma si può notare che il valore URL nel campo [Adresse] del browser è cambiato. È diventato il seguente:
http://localhost/form2/formulaire_get.aspx?rdMarie=sì&C1=uno&C2=due&txtSaisie=programmazione+asp.net&txtMdp=unMotDePasse&areaSaisie=le+basi+della%0D%0Aprogrammazione+web%0D%0A&cmbValeurs=3&lstSimple=1&lstMultiple=2&lstMultiple=4&btnEnvoyer=Invia&secret=uneValeur
Si nota che le scelte effettuate nel modulo si ritrovano nel campo URL. Esaminiamo il contenuto del file [request.txt] che ha memorizzato la richiesta del client:
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
Si nota una richiesta HTTP piuttosto simile a quella inizialmente inviata dal browser quando aveva richiesto il documento senza trasmettere alcun parametro. Ci sono due differenze:
I parametri del modulo sono stati aggiunti dopo l'ID del documento URL nella forma ?param1=val1¶m2=val2&... | |
Il cliente indica con questa intestazione HTTP il codice URL del documento che stava visualizzando quando ha effettuato la richiesta |
Esaminiamo più da vicino come sono stati passati i parametri nel comando GET URL?param1=valore1¶m2=valore2&... HTTP/1.1 dove parami sono i nomi dei controlli del modulo web e valeuri i valori ad essi associati. Di seguito presentiamo una tabella a tre colonne:
- colonna 1: riporta la definizione di un controllo HTML dell'esempio
- colonna 2: mostra come viene visualizzato questo controllo in un browser
- colonna 3: riporta il valore inviato al server dal browser per il controllo della colonna 1 nella forma in cui appare nella richiesta GET dell'esempio
controllo HTML | visualizzazione prima della convalida | valore/i restituito/i |
<input type="radio" value="sì" name="rdMarie" />Sì <input type="radio" checked value="no" name="rdMarie" />No | rdMarie=sì - il valore dell'attributo value del pulsante selezionato dall'utente. | |
<input type="checkbox" value="uno" name="C1" />1 <input type="checkbox" checked value="due" name="C2" />2 <input type="checkbox" value="tre" name="C3" />3 | C1=uno C2=due - valori degli attributi value delle caselle selezionate dall'utente | |
<input type="text" maxlength="30" value="alcune parole" name="txtSaisie" /> | txtInserimento=programmazione+asp.net - testo digitato dall'utente nel campo di inserimento. Gli spazi sono stati sostituiti con il segno + | |
<input type="password" maxlength="12" size="12" value="unaPassword" name="txtMdp" /> | txtMdp=questoÈSegreto - testo digitato dall'utente nel campo di immissione. Il testo effettivamente digitato era "questoèsegreto". L'ultimo carattere è stato perso perché l'attributo maxlength="12" limitava il numero di caratteri a 12. | |
<textarea name="areaSaisie"> riga1 riga2</textarea> | ![]() | areaSaisie=le+basi+di+ la%0D%0A programmazione+web - testo digitato dall'utente nel campo di inserimento. %OD%OA è il segno di fine riga. Gli spazi sono stati sostituiti dal segno + |
<select name="cmbValeurs"> <option value="1">scelta1 </option> <option value="2" selected>opzione2 </option> <option value="3">opzione 3 </option> </select> | cmbValori=3 - valore selezionato dall'utente nell' elenco a selezione singola | |
<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">elenco5 </option> </select> | ![]() | lstSimple=3 - valore selezionato dall'utente nella elenco a selezione singola |
<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> | ![]() | lstMultiple=2 lstMultiple=4 - valori selezionati dall'utente nell' elenco a selezione multipla |
<input type="submit" value="Invia" name="btnInvia" /> | btnEnvoyer=Invia - nome e attributo value del pulsante che è è stato utilizzato per inviare i dati del modulo al server | |
<input type="hidden" name="secret" value="unValore" /> | secret=unValore - attributo value del campo nascosto |
Ci si potrebbe chiedere cosa abbia fatto il server con i parametri che gli sono stati passati. In realtà, nulla. Alla ricezione del 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
Il server web ha trasmesso i parametri da URL ai documenti [http://localhost/form2/formulaire_get.aspx] e c.a.d, ovvero al documento che avevamo creato inizialmente. Non abbiamo scritto alcun codice per recuperare ed elaborare i parametri che il client ci invia. Pertanto, è come se la richiesta del client fosse semplicemente:
È per questo motivo che, in risposta al nostro pulsante [Envoyer], abbiamo ottenuto la stessa pagina ottenuta inizialmente richiedendo URL e [http://localhost/form2/formulaire_get.aspx] senza parametri.
5.3.2. Metodo POST
Il documento HTML è ora configurato in modo che il browser utilizzi il metodo POST per inviare i valori del modulo al server web. A tal fine, copiamo il file [formulaire_get.aspx] in [formulaire_post.aspx] e modifichiamo solo il tag <form> in [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">
Non è necessario sostituire il controller [formulaire_get.aspx.vb], pertanto lo lasciamo così com'è. Richiediamo il nuovo documento tramite URL [http://localhost/form2/formulaire_post.aspx], compiliamo il modulo come per il metodo GET e inviamo i parametri al server con il pulsante [Envoyer]. Dal server otteniamo la seguente pagina di risposta:

Otteniamo quindi lo stesso risultato dei metodi GET e c.a.d: la pagina iniziale. Si noti una differenza: nel campo [Adresse] del browser, i parametri trasmessi non compaiono. Ora esaminiamo la richiesta inviata dal client e memorizzata nel file [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
Nella richiesta HTTP del cliente compaiono alcune novità:
la query GET è stata sostituita dalla query POST. I parametri non sono più presenti nella prima riga della query. Si può notare che ora sono posizionati dopo la query HTTP, dopo una riga vuota. La loro codifica è identica a quella che avevano nella query GET. | |
numero di caratteri “inviati”, c.a.d. Il numero di caratteri che il server web dovrà leggere dopo aver ricevuto le intestazioni HTTP per recuperare il documento inviato dal client. Il documento in questione è in questo caso l’elenco dei valori del modulo. | |
specifica il tipo di documento che il client invierà dopo le intestazioni HTTP. Il tipo [application/x-www-form-urlencoded] indica che si tratta di un documento contenente i valori del modulo. |
Esistono due metodi per trasmettere dati a un server web: GET e POST. Esiste un metodo migliore dell’altro? Abbiamo visto che se i valori di un modulo venivano inviati dal browser con il metodo GET, il browser visualizzava nel proprio campo Adresse il valore richiesto URL nella forma URL?param1=val1¶m2=val2&.... Questo può essere considerato un vantaggio o uno svantaggio:
- un vantaggio se si vuole consentire all’utente di inserire questo URL configurato tra i propri link preferiti
- uno svantaggio se non si desidera che l’utente abbia accesso a determinate informazioni del modulo, come ad esempio i campi nascosti
D'ora in poi, utilizzeremo quasi esclusivamente il metodo POST nei nostri moduli.
5.4. Elaborazione lato server dei valori di un modulo
5.4.1. Presentazione dell’esempio
Ora che abbiamo stabilito il collegamento tra il tag HTML <form method="GET/POST" ...> e il modo in cui il browser invia i valori del modulo, sappiamo come recuperarli sul lato server. È stato il capitolo precedente a fornirci la risposta:
- se il metodo del tag <form> è GET, i valori dei parametri saranno recuperati nella collezione [Request.QueryString]
- se il metodo del tag <form> è POST, i valori dei parametri “inviati” saranno recuperati nella collezione [Request.Form]. A questo punto è necessario fare una precisazione. Il tag <form> può specificare, tramite l’attributo [action], l’URL di destinazione del GET o del POST. Tale URL può essere configurato sia che si tratti di un GET sia di un POST, nella forma action="url?param1=val1¶m2=val2&..". Questi parametri si aggiungono quindi a quelli contenuti tra i tag <form> e </form>, che saranno oggetto di un trasferimento al server tramite un GET o un POST. Poiché fanno parte dell'URL di destinazione, saranno recuperati nella raccolta [Request.QueryString], indipendentemente dal fatto che si tratti di un GET o di un POST.
Ora scriviamo un'applicazione MVC con due viste:
- la prima vista è il modulo precedente. La chiameremo [vue_formulaire].
- la seconda vista è una pagina informativa che elenca i valori inseriti nella prima pagina. Un link consente di tornare al modulo. Chiameremo questa vista [vue_confirmation].
La vista [vue_formulaire] viene inviata all’utente, che la compila e la convalida. Potrebbe apparire così poco prima della convalida:

L’utente utilizza il pulsante [Envoyer] per confermare i dati inseriti. In cambio riceve la seguente vista [vue_validation]:

5.4.2. Il controller dell'applicazione
Nel capitolo precedente abbiamo visto che è possibile affidare il ruolo di controller di un'applicazione MVC al file [global.asax], attraverso il quale transitano tutte le richieste dei client. Abbiamo già presentato un'applicazione MVC costruita in questo modo e qui seguiamo il modello di sviluppo presentato in quell'occasione. Il file [global.asax] sarà il seguente:
È costituito da un’unica riga che fa riferimento al controller contenuto nel file [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)
' si recupera l'azione da eseguire
Dim action As String
If Request.QueryString("action") Is Nothing Then
action = "init"
Else
action = Request.QueryString("action").ToString.ToLower
End If
' si esegue l'azione
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
Il funzionamento del controller è il seguente:
- il controller verifica la presenza, nell'URL di destinazione, di una stringa di parametri contenente il parametro [action]. Se questo parametro è assente, il sistema si comporta come se nella stringa di parametri fosse presente [action=init].
- Sono riconosciute solo due azioni:
- init: al cliente viene fornito il modulo precompilato
- validation: al cliente viene inviata la pagina che conferma i dati inseriti
- se l'azione non è una delle precedenti, si procede come se fosse presente [action=init]. Si potrebbe anche visualizzare una pagina di errore.
5.4.3. Elaborazione dell'azione init
Quando il controller elabora l’azione «init», deve generare un modulo precompilato. È compito della pagina [formulaire.aspx] svolgere questo compito. Il suo codice è il seguente:
<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>
Ritroviamo il codice HTML del modulo esaminato in precedenza, con alcune differenze. Il codice del tag <form> è stato modificato:
<form name="formulaire" method="post" action="?action=validation">
- post: i valori inseriti dall’utente e inviati al server quando verrà utilizzato il pulsante di tipo [submit] saranno inviati tramite il metodo HTTP POST
- azione: la sintassi action="url" serve a indicare l'URL a cui devono essere inviati i valori del modulo. Questo URL può includere una stringa di parametri nella forma param1=val1¶m2=val2&... È ciò che avviene in questo caso, in cui passiamo il parametro [action=validation] per indicare al controller l’azione che deve intraprendere. Si noti che questa stringa di parametri non è preceduta da un indirizzo web. Il browser invierà quindi i parametri del modulo all’indirizzo che gli ha fornito tale modulo. Nel nostro esempio presentato sopra, tale indirizzo è [http://localhost/mvcform1]. Il browser effettuerà quindi una richiesta [POST /mvcform1?action=validation] al server [localhost].
Sono stati aggiunti dei pulsanti per consentire all’utente di deselezionare gli elementi delle liste [lstSimple] e [lstMultiple]:

Ciò si traduce nel seguente codice 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>
Cliccando su un pulsante [Raz] si deseleziona qualsiasi elemento dell'elenco a cui è associato. Prendiamo ad esempio l'elenco [lstMultiple]. Cliccando sul pulsante corrispondente [Raz], viene eseguita la funzione JavaScript [raz(lstMultiple)]. Ricordiamo che il codice JavaScript di un documento HTML visualizzato da un browser viene eseguito dallo stesso browser e non dal server. JavaScript è un linguaggio molto completo che consente di conferire un aspetto dinamico alle pagine senza l’intervento del server. La funzione [raz] è la seguente:
Questa funzione riceve un parametro che è un oggetto JavaScript che rappresenta un elenco HTML. Questo oggetto possiede proprietà e metodi. Una delle sue proprietà è [selectedIndex], il cui valore è il numero della prima opzione selezionata nell’elenco HTML. Se non ce n’è nessuna, questa proprietà assume il valore -1. Viceversa, assegnare un valore a questa proprietà equivale a selezionare un nuovo elemento nell’elenco HTML, mentre assegnargli il valore -1 equivale a non avere alcun elemento selezionato. È proprio ciò che viene fatto in questo caso.
Si noti infine che il codice di presentazione [formulaire.aspx] non è accompagnato da un controller [formulaire.aspx.vb]. Infatti, nel documento HTML non vi è alcuna parte dinamica generata dal server, quindi non è necessario disporre di un controller.
5.4.4. Elaborazione dell’azione di convalida
Quando il controller elabora l’azione «validazione», deve generare una pagina che elenchi i valori inseriti dall’utente. È compito della pagina [validation.aspx] svolgere questa funzione. Visivamente, la pagina si presenta come segue:

Il suo codice HTML è il seguente:
<%@ 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>
Le parti dinamiche <%=variabile%> del documento vengono calcolate dal controller [validation.aspx.vb] associato:
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
'si recuperano i parametri inviati
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 il valore del campo [champ] dalla richiesta inviata
' qualcosa?
If Request.Form(champ) Is Nothing Then Return ""
' si recuperano i valori del 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
Il calcolo dei valori da visualizzare viene effettuato nella procedura [Form_Load]. Il valore di un campo "inviato" viene ottenuto tramite la funzione getValue(C), dove C è il nome del campo. I punti chiave di questa funzione sono i seguenti:
- se C non è presente nella stringa di parametri inviata, allora si restituisce la stringa vuota come valore di C
- altrimenti si ottiene l’array dei valori del campo C tramite [Request.Form.GetValues(C)]. Questi vengono concatenati in una stringa di caratteri nella forma [val1][val2]...[valn], dove [vali] è il valore n. i del campo C
Il campo [areaSaisie] viene trattato in modo particolare. Il suo valore viene inviato dal browser nella forma areaSaisie=riga1\r\nriga2\r\n... dove \r è il carattere con codice ASCII 13 (ritorno a capo) e \n il carattere con codice ASCII 10 (salto di riga). La funzione getValue(areaSaisie) è quindi la stringa "riga1\r\nriga2\r\n...". Questa stringa viene suddivisa in righe dal metodo [Regex.Split]. Si ottiene così un array di stringhe {riga1,riga2,...}. Questo array viene trasformato nella stringa "riga1,riga2,..." dal metodo [String.Join]. È quest'ultima stringa che verrà visualizzata come valore del campo [areaSaisie]. Lo scopo era quello di mostrare come ottenere le diverse righe di un campo HTML di tipo [TextArea].
5.4.5. Test
Inseriamo tutti i file (global.asax, global.asax.vb, formulaire.aspx, validation.aspx, validation.aspx.vb) in una cartella <application-path>. Avviamo il server Cassini con i parametri (<application-path>,/mvcform1). Creiamo nella cartella <application-path> un file vuoto denominato [default.aspx], quindi richiediamo l’URL [http://localhost/mvcform1]. Poiché [/mvcform1] è il percorso virtuale di una cartella e non di un documento, il server web visualizzerà il documento [default.aspx], se presente. Ecco perché lo abbiamo creato. Prima di visualizzarlo, verrà eseguito lo script [global.asax], che alla fine farà visualizzare la pagina [formulaire.aspx]. Ecco perché il file [default.aspx] può essere vuoto.
Supponiamo che il modulo convalidato sia il seguente:

L'utilizzo del pulsante [Envoyer] restituisce la seguente pagina:

Notiamo innanzitutto l’URL della risposta: [http://localhost/mvcform1/?action=validation]. Si tratta del valore URL dell’attributo [action] del tag <form> del modulo [formulaire.aspx]:
<form name="formulaire" method="post" action="?action=validation">
Esaminiamo uno per uno i valori ottenuti per i diversi campi del modulo:
campo | valore | HTML | commenti |
rdMarie | sì | <input type="radio" value="sì" name="rdMarie">Sì <input type="radio" checked value="no" name="rdMarie">No | il valore ottenuto è l'attributo [value] del pulsante selezionato |
C1 | un | <input type="checkbox" value="uno" name="C1">1 | idem |
C2 | due | <input type="checkbox" checked value="due" name="C2">2 | idem |
C3 | <input type="checkbox" value="tre" name="C3">3 | questo pulsante non è stato selezionato dall'utente. Il suo valore non è stato quindi inviato dal browser. Nel codice, la condizione [Request.Form("C3") is Nothing] è risultata quindi vera. | |
txtSaisie | Programmazione asp.net | <input type="text" ... name="txtSaisie"> | il valore ottenuto è il testo presente nel campo di immissione al momento della convalida |
txtMdp | mdp | <input type="password" ...name="txtMdp"> | idem |
areaSaisie | le basi della programmazione web | <textarea name="areaSaisie"> ...</textarea> | idem |
cmbValeurs | 3 | <select name="cmbValeurs"> ... <option value="3">scelta3</option> </select> | il valore ottenuto è l'attributo [value] dell'opzione selezionata |
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> | i valori ottenuti corrispondono agli attributi [value] delle opzioni selezionate |
segreto | uneValeur | <input type="hidden" name="secret" value="unValore"> | il valore ottenuto è l'attributo [value] del campo nascosto |
Ora concentriamoci sugli elenchi. Supponiamo che al momento della convalida lo stato del modulo sia il seguente:

- l'opzione [choix1] è selezionata nel comboBox
- nessuna opzione è selezionata negli altri due elenchi. Per ottenere questo risultato sono stati utilizzati i pulsanti [Raz].
Ecco la pagina restituita dopo la convalida:

Quando non viene selezionato alcun valore in un elenco, il browser non invia alcun parametro relativo a tale elenco. Nel codice di [validation.aspx.vb], le espressioni [Request.Form("lstSimple")] e [Request.Form("lstMultiple")] sono quindi uguali alla costante [Nothing], da cui deriva il risultato visualizzato sopra.
5.5. Mantenere lo stato di una pagina
5.5.1. Mantenere lo stato di una pagina con una sessione
Duplichiamo l'intera applicazione precedente in una nuova cartella. Aggiungiamo un link nella pagina QZXW2HTMLP001742ZQ che consenta all'utente di tornare al modulo:

La modifica da apportare alla pagina [validation.aspx] consiste nell’aggiungere il link:
.....
<TR>
<TD width="84">secret</TD>
<TD><%=secret%></TD>
</TR>
</TABLE>
<P>
<a href="?action=formulaire">Retour au formulaire</a>
</P>
</body>
</HTML>
L'attributo [href] del link ha come valore un URL con un unico parametro, [action=formulaire], che consente al server di sapere che deve visualizzare il modulo così com'era al momento della convalida. C'è quindi una differenza rispetto all'azione [init], che visualizza un modulo predefinito. L'URL con parametro [?action=formulaire], infatti, non ha un URL. Questo sarà quindi lo stesso che ha permesso la visualizzazione della pagina di convalida. Se ricordiamo lo studio precedente, questa è l’URL della cartella dell’applicazione. La richiesta passerà quindi attraverso il controller. Quest’ultimo deve ora elaborare l’azione [formulaire]. Il codice di [global.asax.vb] viene modificato come segue:
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
' si recupera l'azione da eseguire
Dim action As String
If Request.QueryString("action") Is Nothing Then
action = "init"
Else
action = Request.QueryString("action").ToString.ToLower
End If
' si esegue l'azione
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
Nel caso in cui l'azione sia "modulo", ci si limita a inoltrare la richiesta alla pagina [formulaire.aspx]. Sappiamo che questa pagina visualizza un modulo predefinito in cui non vi sono parti variabili. Pertanto, questa pagina non può visualizzare il modulo con i valori che aveva al momento della convalida. In questa sede si intende mettere in evidenza questo aspetto. Se tutti i file dell’applicazione sono stati collocati in <application-path>, avviamo Cassini con i parametri (<application-path>,/mvcform2) e poi richiediamo l’URL [http://localhost/mvcform2]. Otteniamo la seguente pagina (vista parziale):

Compiliamo il modulo come segue e poi lo inviamo:

Otteniamo la seguente pagina di conferma:

Utilizziamo il link [Retour au formulaire] presente (ma non visualizzato) nella pagina sopra riportata. Otteniamo la seguente risposta dal server:

Notiamo che:
- l'URL richiesto contiene effettivamente il parametro action=form, come desiderato
- il modulo visualizzato ha perso i valori inseriti.
Sappiamo perché non ritroviamo i valori inseriti. Se esaminiamo il codice del documento [formulaire.aspx], notiamo che è tutto statico e che, di conseguenza, è costretto a visualizzare ogni volta la stessa pagina. È evidente che dobbiamo rendere dinamico questo codice. Dovrà visualizzare i valori convalidati dall’utente. Ma dove memorizzarli?
Ricordiamo la regola d’oro del protocollo stateless HTTP:
- viene richiesta l’URL [http://localhost/mvcform2] – viene ricevuta una risposta. Una connessione TCP-IP è stata aperta tra il client e il server all’inizio della richiesta e chiusa al termine della risposta.
- L'utente inserisce e conferma i dati. Viene richiesta l'URL [http://localhost/mvcform2/?action=validation] - viene ricevuta una risposta. Una nuova connessione TCP-IP è stata aperta e poi chiusa tra i due partner.
- L'utente utilizza il link [Retour au formulaire]. Viene richiesta l'URL [http://localhost/mvcform2/?action=formulaire] e viene ricevuta una risposta. Una nuova connessione TCP-IP è stata nuovamente aperta e poi chiusa tra i due partner.
I cicli richiesta-risposta sono indipendenti l’uno dall’altro poiché ciascuno di essi utilizza una nuova connessione TCP-IP. Quando un'applicazione client-server utilizza un'unica connessione TCP-IP per una serie di scambi, il server può identificare un client tramite la sua connessione. Può quindi memorizzare informazioni che assocerà a una connessione specifica e tenere così traccia degli scambi. Quando gli scambi avvengono su connessioni diverse, il server non può identificare un client in base a una connessione. È necessario un altro metodo. Ne abbiamo presentato uno nel capitolo precedente: il meccanismo della sessione. Esso consente ai cicli richiesta-risposta di memorizzare informazioni in un oggetto [Session] accessibile a tutti i cicli successivi.
Ora che disponiamo di un’applicazione MVC con sessione, non possiamo più utilizzare il file [global.asax] come controller, come illustrato nel capitolo precedente. Il ruolo di controller dell’applicazione deve essere svolto da una pagina specifica dedicata a tale scopo. In questo caso, sarà la pagina [main.aspx]. Procederemo come segue:
- quando l’utente convaliderà i propri dati (azione=convalida), il controller [main.aspx.vb] li memorizzerà nella sessione corrente prima di visualizzare la pagina di convalida.
- quando sarà necessario visualizzare il modulo con i valori inseriti (azione=modulo), il controller [main.aspx.vb] li recupererà dalla sessione e li inserirà nel contesto prima di visualizzare il modulo.
5.5.2. Il nuovo controller dell’applicazione
Il controller dell'applicazione è costituito dai due file [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
' si recupera l'azione da eseguire
Dim action As String
If Request.QueryString("action") Is Nothing Then
action = "init"
Else
action = Request.QueryString("action").ToString.ToLower
End If
' si esegue l'azione
Select Case action
Case "init"
' si visualizza il modulo precompilato
Context.Items("formulaire") = initForm()
Server.Transfer("formulaire.aspx", True)
Case "validation"
' si visualizza la pagina di conferma dopo aver salvato i valori inviati nella sessione
Session.Item("formulaire") = Request.Form
Server.Transfer("validation.aspx", True)
Case "formulaire"
' si visualizza il modulo con i valori prelevati dalla sessione
Context.Items("formulaire") = Session.Item("formulaire")
Server.Transfer("formulaire.aspx", True)
Case Else
' viene visualizzato il modulo precompilato
Context.Items("formulaire") = initForm()
Server.Transfer("formulaire.aspx", True)
End Select
End Sub
Private Function initForm() As NameValueCollection
' si inizializza il modulo
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
Si ritrova l'essenza della struttura del controller dell'applicazione esaminata in precedenza, con le seguenti differenze:
- il controller opera all’interno della procedura [Form_Load]
- nel caso dell'azione [validation], i valori del modulo presenti in [Request.Form] vengono memorizzati nella sessione associata alla chiave "modulo". Successivamente l'esecuzione viene trasferita alla pagina [validation.aspx] che visualizzerà tali valori.
- Per le altre azioni, l’esecuzione viene trasferita in ogni caso alla pagina [formulaire.aspx]. Quest’ultima si aspetta nel proprio contesto una chiave “formulario” che sarà associata a un oggetto del tipo [Request.form], c.a.d o del tipo [NameValueCollection]. Tale oggetto deve contenere la raccolta dei valori dei campi del modulo.
- nel caso in cui l’azione sia [init] o un’azione non riconosciuta, la raccolta dei valori viene costruita arbitrariamente dalla funzione [initForm].
- nel caso in cui l'azione sia [formulaire], tale raccolta è la raccolta [Request.Form] che era stata inserita nella sessione dall'azione [validation]
5.5.3. Il nuovo modulo
Poiché l’applicazione non visualizza più lo stesso contenuto nel modulo, quest’ultimo deve essere generato dinamicamente. La nuova pagina [formulaire.aspx] diventa la seguente:
<%@ 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>
Commentiamo le variabili dinamiche che compaiono nel codice HTML:
variabile | ruolo |
avrà il valore "checked" se il pulsante di opzione [oui] deve essere selezionato, altrimenti il valore "" | |
lo stesso vale per il pulsante di opzione [non] | |
lo stesso vale per la casella di controllo [C1] | |
lo stesso vale per la casella di controllo [C2] | |
lo stesso vale per la casella di selezione [C3] | |
il testo da inserire nel campo [txtSaisie] | |
il testo da inserire nel campo [txtMdp] | |
il testo da inserire nel campo [areaSaisie] | |
il testo HTML delle opzioni dell'elenco a discesa [cmbValeurs] | |
il testo HTML delle opzioni dell'elenco a discesa [lstSimple] | |
il testo HTML delle opzioni dell'elenco a discesa [lstMultiple] | |
I valori di queste variabili vengono calcolati dal controller della pagina [formulaire.aspx.vb]:
Imports Microsoft.VisualBasic
Imports System.Collections.Specialized
Public Class formulaire
Inherits System.Web.UI.Page
' campi fissi del modulo
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"}
' campi dinamici del modulo
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
' si recupera la richiesta precedente dalla sessione
Dim form As NameValueCollection
If Not Context.Items("formulaire") Is Nothing Then
form = Context.Items("formulaire")
Else
form = New NameValueCollection
End If
' si prepara la pagina da visualizzare
' pulsanti di opzione
rdouichecked = ""
rdnonchecked = "checked"
If isEqual(form("rdMarie"), "oui") Then
rdouichecked = "checked"
rdnonchecked = ""
End If
' caselle di controllo
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"
' campi di immissione
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
' elenchi
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
' restituisce il codice HTML delle opzioni di un tag <select>
' valori: tabella dei valori delle opzioni del tag
' etichette: tabella delle etichette delle opzioni del tag
' selezioni: opzioni da selezionare
Dim iValeur As Integer
Dim iSelection As Integer
Dim selected As String
Dim toString As String = ""
' si scorre l'elenco dei valori delle opzioni
For iValeur = 0 To valeurs.Length - 1
' si verifica se il valore corrente deve essere selezionato
selected = "" : iSelection = 0
Do While iSelection < sélections.Length And selected = ""
If valeurs(iValeur) = sélections(iSelection) Then selected = "selected"
iSelection += 1
Loop
' si inserisce il codice HTML dell'opzione
toString += "<option " + selected + " value='" + valeurs(iValeur) + "'> " _
+ libelles(iValeur) + "</option>" + ControlChars.CrLf
Next
' si restituisce il risultato
Return toString
End Function
Private Function isEqual(Byval champ As Object, ByVal valeur As String) As Boolean
' restituisce vero se il campo è uguale al valore
If champ Is Nothing OrElse champ.ToString <> valeur Then
Return false
Else
Return true
End If
end function
End Class
Quando la pagina [formulaire.aspx] inizia a essere eseguita, individua nel proprio contesto una chiave "modulo" associata alla raccolta di valori dei campi che deve visualizzare.
' si recupera la query precedente dalla sessione
Dim form As NameValueCollection
If Not Context.Items("formulaire") Is Nothing Then
form = Context.Items("formulaire")
Else
form = New NameValueCollection
End If
Ci si potrebbe chiedere perché si verifichi l'esistenza di [Context.Items("formulaire")]. Infatti, il controller assegna un valore a questo oggetto in ogni caso. Tuttavia, nulla impedisce al client di richiedere direttamente la pagina [formulaire.aspx] senza passare attraverso il controller. Se ciò dovesse accadere, il codice precedente opererà con una collezione di valori vuota, ma non si verificherà alcun "arresto anomalo".
Il codice esplora la collezione di valori ricevuti per calcolare tutte le variabili dinamiche della pagina HTML ad essa associata. Sebbene sia lungo, questo codice non è particolarmente complicato e lasciamo al lettore il compito di approfondirlo per non appesantire questa spiegazione. Ci soffermeremo tuttavia sul modo in cui viene generato il codice HTML dalle tre liste di tipo [select]. Questo codice viene generato dalla seguente funzione:
Private Function getOptions(ByRef valeurs() As String, ByRef libelles() As String, ByRef sélections() As String) As String
' restituisce il codice HTML delle opzioni di un tag <select>
' valori: array dei valori delle opzioni del tag
' etichette: tabella delle etichette delle opzioni del tag
' selezioni: opzioni da selezionare
Dim iValeur As Integer
Dim iSelection As Integer
Dim selected As String
Dim toString As String = ""
' si scorre l'elenco dei valori delle opzioni
For iValeur = 0 To valeurs.Length - 1
' si verifica se il valore corrente deve essere selezionato
selected = "" : iSelection = 0
Do While iSelection < sélections.Length And selected = ""
If valeurs(iValeur) = sélections(iSelection) Then selected = "selected"
iSelection += 1
Loop
' si inserisce il codice HTML dell'opzione
toString += "<option " + selected + " value='" + valeurs(iValeur) + "'> " _
+ libelles(iValeur) + "</option>" + ControlChars.CrLf
Next
' si restituisce il risultato
Return toString
End Function
Ricordiamo che le opzioni di un tag <select> corrispondono al seguente codice HTML:
Per ogni opzione, occorre quindi generare tre informazioni:
- il valore dell'opzione nell'attributo [value]
- il testo dell’opzione tra i tag <option> e </option>
- la parola chiave [selected] se l’opzione deve essere selezionata nell’elenco
Per generare queste tre informazioni per ciascuna delle opzioni, la funzione [getOptions] riceve tre valori:
- l'array dei valori delle opzioni in [valeurs]
- l'array dei testi delle opzioni in [libelles]
- l'array dei valori da selezionare in [sélections]
5.5.4. La pagina di convalida
La pagina di convalida rimane invariata:
[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
'si recuperano i parametri inviati
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")
' li si salva nella sessione
'Session("modulo") = Request.Form
End Sub
Private Function getValue(ByVal champ As String) As String
' recupera il valore del campo [champ] dalla richiesta inviata via POST
' qualcosa?
If Request.Form(champ) Is Nothing Then Return ""
' si recuperano i valori del 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. I test
I file [main.aspx, main.aspx.vb,formulaire.aspx,formulaire.aspx.vb, validation.aspx, validation.aspx.vb] vengono inseriti in <application-path> e Casini viene avviato con i parametri (<application-path>,/mvcform3). Successivamente, richiediamo l'URL [http://localhost/mvcform3/main.aspx]. Otteniamo il modulo pre-inizializzato:

Compiliamo il modulo come segue:

Utilizziamo il pulsante [Envoyer] riportato sopra. Otteniamo la seguente risposta dal server:

Utilizziamo il link [Retour au formulaire] riportato sopra per tornare al modulo. Otteniamo la seguente nuova risposta:

Il modulo appare esattamente come lo avevamo inviato.
5.5.6. Conclusione
L'esempio precedente ci ha mostrato che è possibile mantenere lo stato di una pagina nel corso dei cicli di richiesta-risposta tra il client e il server. Tuttavia, questo lavoro non è banale. Vedremo in un capitolo successivo che con ASP.NET è possibile lasciare che sia il server a ripristinare autonomamente lo stato di una pagina.



