5. Gestione dell'interfaccia utente
5.1. Introduzione
Nella relazione client-server sul web, il client invia informazioni al server sotto forma di una stringa di parametri [param1=val1¶m2=val2&...]. Nei nostri esempi precedenti, abbiamo spesso creato questa stringa manualmente richiedendo URL del tipo [http://localhost/appli? param1=val1¶m2=val2&...]. In realtà, le informazioni che il client invia al server provengono dai moduli compilati dall'utente. In questo capitolo vedremo come creare questi moduli. Introdurremo inoltre lo strumento WebMatrix, che ci consentirà di progettare interfacce utente. L'installazione di questo strumento è descritta nelle appendici.
5.2. Il linguaggio HTML
5.2.1. Un esempio
Consideriamo il seguente esempio, creato con [Web Matrix], che visualizza:
- una tabella
- un'immagine
- un link

Avvia [WebMatrix] e seleziona l'opzione [File/Nuovo file]:

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

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

Per inserire un elemento da questa tavolozza, è sufficiente fare doppio clic su di esso e poi posizionarlo nella finestra [Design]. La modalità [HTML] consente di costruire il documento HTML utilizzando un editor di testo. Ciò richiede la conoscenza della sintassi HTML. Nella scheda [HTML] è stato generato uno scheletro di documento:

La finestra [HTML] è molto utile per chi non ha familiarità con l'HTML. Si crea il documento nella finestra [Design] e si controlla il codice HTML generato nella finestra [HTML]. In questo modo, si acquisisce gradualmente padronanza dell'HTML e si può lavorare rapidamente utilizzando esclusivamente l'editor di testo, senza ricorrere alla modalità [Design]. Ora mostreremo come creare il documento HTML presentato all'inizio di questa sezione. Stiamo lavorando nella finestra [Design]. Per prima cosa, inseriamo direttamente la prima riga di testo:

- aggiungiamo il componente [Linea orizzontale] dalla tavolozza dei componenti:

- aggiungiamo il componente [Tabella]:

- posizioniamo il cursore sulla terza riga della tabella per eliminarla utilizzando l'opzione [HTML/Modifica tabella/Elimina riga tabella]. Quindi inseriamo il testo previsto in ciascuna cella:

- posizioniamo il cursore in una delle celle della tabella ed esaminiamo le sue proprietà. La finestra delle proprietà viene visualizzata in basso a destra dell'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 contenente la cella. Facciamo clic sull'elenco a discesa (clicca per vedere gli elementi HTML padre) in alto per selezionare l'oggetto <TABLE>:

- L'oggetto <TABLE> ha una proprietà [border] che imposta la larghezza del bordo che circonda le celle della tabella. Qui, impostiamo border=1.

- Ora modificheremo gli attributi dell'oggetto <TD> nella cella (1,2) per impostare align=Center e width=200 (pixel). Il testo sarà centrato nella cella (align=center) e la cella avrà una larghezza di 200 pixel. Per vedere la modifica, 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 [immagine] nella 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 [qui] in un link all'URL [http://istia.univ-angers.fr]. Per farlo, lo selezioniamo e poi scegliamo l'opzione [HTML/Inserisci collegamento ipertestuale]:

- 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>
Abbiamo ancora alcuni dettagli da sistemare. Innanzitutto, vorremmo dare un titolo al nostro documento. [WebMatrix] non consente di farlo in modalità [Design]. Nella scheda [HTML], sostituiamo la sezione <head>..</head> con quanto segue:
Inoltre, vorremmo che il testo [HTML - 1] apparisse con caratteri più grandi. Il tag <Hi>text</Hi> consente di impostare la dimensione del testo, con "i" che va da 1 a 6, dal più grande al più piccolo. Qui useremo H2. Il tag
diventa:
La finestra [Design] riflette le nostre modifiche:

Non resta che testarla utilizzando l'opzione [View/Start] o [F5]. [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 quali parametri sono stati utilizzati per avviare [Cassini]:

Abbiamo illustrato le nozioni di base sulla creazione di una pagina HTML con [WebMatrix]. Invitiamo i lettori a creare altre pagine HTML e a controllare ogni volta il codice HTML generato. A poco a poco, saranno in grado di creare una pagina senza utilizzare la modalità [Design]. Un documento HTML presenta generalmente la seguente struttura:
L'intero documento è racchiuso tra i tag <html>...</html>. È composto da due parti:
<head>...</head>: questa è la parte non visualizzabile del documento. Fornisce informazioni al browser che visualizzerà il documento. Spesso contiene il tag <title>...</title>, che imposta il testo che apparirà nella barra del titolo del browser. Può contenere anche altri tag, compresi quelli che definiscono le parole chiave del documento, che vengono poi utilizzate dai motori di ricerca. Questa sezione può contenere anche script, solitamente scritti in JavaScript o VBScript, che verranno eseguiti dal browser.
<attributi del body>...</body>: Questa è la sezione che verrà visualizzata dal browser. I tag HTML contenuti in questa sezione indicano al browser il layout visivo "desiderato" per il documento. Ogni browser interpreta questi tag a modo suo. Di conseguenza, due browser potrebbero visualizzare lo stesso documento web in modo diverso. Questa è generalmente una delle sfide che devono affrontare i 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>
HTML | Tag HTML ed esempi |
<title>HTML1</title> HTML1 apparirà nella barra del titolo del browser quando il documento viene visualizzato | |
<horizontal> : visualizza una linea orizzontale | |
<attributi tabella>....</table> : per definire la tabella <tr attributi>... : per definire una riga <td attributi>... : per definire una cella esempi: <table border="1">...: l'attributo border definisce lo spessore del bordo della tabella <td align="center" width="200">cell(1,2) : definisce una cella il cui contenuto sarà cell(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 collegamento si trova in un documento web accessibile tramite l'URL http://localhost/exemple1.htm. Pertanto, il browser richiederà l'URL http://localhost/univ01.gif per recuperare l'immagine a cui si fa riferimento qui. | |
<a href="http://istia.univ-angers.fr">qui: fa sì che il testo "qui" funga da collegamento all'URL http://istia.univ-angers.fr. |
In questo semplice esempio, possiamo vedere che per costruire l'intero documento, il browser deve effettuare due richieste al server:
http://localhost/exemple1.htm per recuperare il codice sorgente HTML del documento
http://localhost/univ01.gif per recuperare l'immagine univ01.gif
5.2.2. Creazione di un modulo
Lo scopo di un modulo HTML è quello di presentare all'utente una pagina di immissione dati simile ai moduli di immissione presenti in Windows. Il modulo di immissione viene inviato al browser come documento HTML. Il browser visualizza il modulo all'utente, che lo compila e lo invia utilizzando un pulsante con quella funzione. Il browser trasmette quindi i valori inseriti al server per l'elaborazione. Vedremo che non invia l'intero modulo al server, ma solo i valori inseriti. L'esempio seguente mostra 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>
La mappatura tra elementi visivi e tag HTML è la seguente:
Controllo visivo | Tag HTML |
<form name="form" method="post"> | |
<input type="text" maxlength="30" value="a few words" name="txtInput" /> | |
<input type="password" maxlength="12" size="12" value="aPassword" name="txtMdp" /> | |
<textarea name="inputArea">riga1 riga2</textarea> | |
<input type="radio" value="yes" 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">opzione1</option> <option value="2" selected>opzione2</option> <option value="3">opzione3</option> </select> | |
<select size="3" name="lstSimple"> <option value="1" selected>elenco1</option> <option value="2">elenco2</option> <option value="3">elenco3</option> <option value="4">elenco4</option> <option value="5">elenco5</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="aValue" /> | |
<input type="submit" value="Invia" name="submitButton" /> | |
<input type="reset" value="Reset" name="btnReset" runat="server" /> | |
<input onclick="clear()" type="button" value="Cancella" name="btnClear" /> |
Esaminiamo questi diversi controlli.
5.2.2.1. Il
<form name="form" method="post"> |
<form name="..." method="..." action="...">...</form> | |
name="formexample": nome del modulo method="..." : metodo utilizzato dal browser per inviare i valori raccolti nel modulo al server web 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"). Ciò vale per tutti i controlli presenti all'interno di un modulo. Questo 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 inserite dall'utente tramite la tastiera o il mouse e inviarle a un URL di un server web. Quale? Quello a cui fa riferimento l'attributo action="URL". Se questo attributo manca, le informazioni saranno inviate all'URL del documento in cui si trova il modulo. In che modo un client web invia le informazioni (i dati contenuti nel modulo) a un server web? Ne abbiamo parlato in dettaglio. Può utilizzare due metodi diversi chiamati POST e GET. L'attributo method="method" del tag <form>, dove method è impostato su GET o POST, indica al browser quale metodo 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="txtInput" /> <input type="password" maxlength="12" size="12" value="aPassword" name="txtMdp" /> |
<input type="..." name="..." size=".." value=".."> Il tag input esiste per vari controlli. È l'attributo type che distingue questi diversi controlli l'uno dall'altro. | |
type="text": specifica che si tratta di un campo di immissione testo type="password": i caratteri nel campo di immissione vengono sostituiti da asterischi (*). Questa è l'unica differenza rispetto a un normale campo di immissione. Questo tipo di controllo è adatto per l'immissione di password. size="12": numero di caratteri visibili nel campo — non impedisce l'inserimento di più caratteri maxlength="30": imposta il numero massimo di caratteri a 30 — il browser è responsabile dell'applicazione di questo attributo name="txtInput": nome del controllo value="alcune parole": testo che verrà visualizzato nel campo di immissione. |
5.2.2.3. Campo di immissione multilinea

<textarea name="inputArea">riga1 riga2</textarea> |
<textarea ...>testo</textarea> visualizza un campo di immissione multilinea con testo iniziale all'interno | |
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="yes" name="rdMarie" />Sì <input type="radio" checked value="no" name="rdMarie" />No |
<input type="radio" attribute2="value2" ..../>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: solo uno di essi può essere selezionato. value="value": valore assegnato al pulsante di opzione. Non confondere questo valore con il testo visualizzato accanto al pulsante di opzione. Il testo 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="one" name="C1" />1 <input type="checkbox" checked value="due" name="C2" />2 <input type="checkbox" value="tre" name="C3" />3 |
![]()
<input type="checkbox" attribute2="value2" ..../>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 di controllo con lo stesso nome formano un gruppo di caselle di controllo associate. value="value": valore assegnato alla casella di controllo. Non confondere questo valore con il testo visualizzato accanto al pulsante di opzione. Il testo serve solo a scopo di 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="cmbValues"> <option value="1">scelta1</option> <option value="2" selected>opzione2</option> <option value="3">Opzione 3</option> </select> |
![]()
<select size=".." name=".."> <option [selected="selected"] [value="value"]>testo</option> ... </select> visualizza il testo tra i tag <option>...</option> in un elenco | |
name="cmbValues": nome del controllo. size="1": numero di voci visibili dell'elenco. size="1" rende l'elenco equivalente a una casella combinata. Questo è il valore predefinito se l'attributo [size] è assente. selected="selected": se questo attributo è presente per una voce dell'elenco, tale voce appare selezionata nell'elenco. Nel nostro esempio sopra, la voce dell'elenco "choice2" appare come voce selezionata nella casella combinata quando viene visualizzata per la prima volta. value="value": imposta il valore da inviare al server se la voce viene selezionata. 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>list1</option> <option value="2">list2</option> <option value="3">elenco3</option> <option value="4">elenco4</option> <option value="5">elenco5</option> </select> |

<select size=".." name=".."> <option [selected] [value="value"]>...</option> ... </select> visualizza il testo tra i tag <option>...</option> in un elenco | |
gli stessi dell'elenco a discesa che visualizza un solo elemento. Questo controllo differisce dal precedente elenco a discesa 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="value"]>...</option> ... </select> visualizza il testo tra i tag <option>...</option> in un elenco | |
multiple: consente la selezione di più elementi nell'elenco. Nell'esempio sopra, gli elementi list1 e list3 sono entrambi selezionati. |
5.2.2.9. Pulsante
<input onclick="clear()" type="button" value="Cancella" name="btnClear" /> |
![]()
<input type="button" value="..." name="..." onclick="clear()" ....> | |
type="button": definisce un controllo pulsante. Esistono altri due tipi di pulsanti: submit e reset. value="Cancella": il testo visualizzato sul pulsante onclick="function()": 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 sopra riportata è sintassi JavaScript. Se gli script sono scritti in VBScript, si scriverebbe onclick="function" senza le parentesi. La sintassi rimane la stessa se è necessario passare dei parametri alla funzione: onclick="function(val1, val2,...)" Nel nostro esempio, cliccando sul pulsante "Cancella" viene chiamata la seguente funzione JavaScript: La funzione clear visualizza un messaggio: ![]() |
5.2.2.10. Pulsante Invia
<input type="submit" value="Invia" name="btnSubmit" /> |
![]()
<input type="submit" value="Invia" name="btnSend"> | |
type="submit": definisce il pulsante come pulsante per l'invio dei dati del modulo al server web. Quando l'utente fa clic su questo pulsante, il browser invierà i dati del modulo all'URL definito nell'attributo action del tag <form>, utilizzando il metodo definito dall'attributo method dello stesso tag. value="Invia": il testo visualizzato sul pulsante |
5.2.2.11. Pulsante di reset
<input type="reset" value="Reset" name="btnReset" runat="server" /> |
![]()
<input type="reset" value="Reset" name="btnReset"> | |
type="reset": definisce il pulsante come pulsante di reset del modulo. Quando l'utente fa clic su questo pulsante, il browser ripristinerà il modulo allo stato in cui è stato ricevuto. value="Reset": il testo visualizzato sul pulsante |
5.2.2.12. Campo nascosto
<input type="hidden" name="secret" value="aValue" /> |
<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 visualizzato all'utente. Tuttavia, se l'utente chiedesse 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="aValue": valore del campo nascosto. Qual è lo scopo del campo nascosto? Consente al server web di conservare le informazioni tra le richieste di un client. Si consideri un'applicazione di shopping online. Il client acquista un articolo iniziale art1 in quantità q1 sulla prima pagina di un catalogo e poi passa a una nuova pagina del catalogo. Per ricordare che il client ha acquistato q1 articoli di art1, il server può inserire queste due informazioni in un campo nascosto nel modulo web della nuova pagina. In questa nuova pagina, il cliente acquista q2 unità dell'articolo art2. Quando i dati di questo secondo modulo vengono inviati al server, il server non solo riceverà le informazioni (q2,art2) ma anche (q1,art1), che fanno anch'esse parte del modulo come campo nascosto che non può essere modificato dall'utente. Il server web inserirà quindi le informazioni (q1,art1) e (q2,art2) in un nuovo campo nascosto e invierà una nuova pagina del catalogo. E così via. |
5.3. Invio dei valori del modulo a un server web tramite un browser
Sappiamo già, dal capitolo precedente, come un client trasmette le informazioni al server. Lo fa tramite:
- una richiesta HTTP GET: url?param1=va1¶m2=val2&....
- una richiesta HTTP POST 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 impostato su GET o POST. Questo è ciò che dimostreremo ora. La pagina che abbiamo esaminato in precedenza è una pagina statica. Per accedere alle intestazioni HTTP inviate dal browser che richiede questo documento, la convertiremo in una pagina dinamica per un server web .NET (IIS o Cassini). Il codice statico precedente viene inserito in un file denominato [form_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 [form_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
' saves the current query in request.txt of the page folder
Dim requestFileName As String = Me.MapPath(Me.TemplateSourceDirectory) + "\request.txt"
Me.Request.SaveAs(requestFileName, True)
End Sub
End Class
Ogni volta che viene richiamato il documento [form_get.aspx], la richiesta del client verrà salvata in un file [request.txt] dalla procedura Page_Init. Abbiamo già incontrato questa modalità di funzionamento, quindi non commenteremo ulteriormente il controller.
5.3.1. Metodo GET
Eseguiamo un test iniziale, in cui 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 è stata registrata 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 avviene sempre quando l'URL viene fornito dall'utente. Compiliamo il modulo come segue:

Utilizziamo il pulsante [Invia] qui sopra. Il suo codice HTML è il seguente:
Quando si fa clic sul pulsante [Invia], il browser invia i parametri del modulo (il tag <form>) all'URL specificato nell'attributo [action] del tag <form action="URL">, se presente. Se questo attributo non esiste, i parametri del modulo vengono inviati all'URL che ha fornito il modulo. È il caso in questione. Il pulsante [Invia] dovrebbe quindi attivare una richiesta dal browser all'URL [http://localhost/form2/formulaire_get.aspx] con i parametri del modulo inclusi. Poiché la pagina [formulaire_get.aspx] memorizza la richiesta ricevuta, dovremmo essere in grado di vedere come il client ha inviato questi parametri. Proviamo. Facciamo clic sul pulsante [Invia]. Riceviamo la seguente risposta dal browser:

Questa è la pagina iniziale, ma si può notare che l'URL è cambiato nel campo [Indirizzo] del browser. È diventato il seguente:
http://localhost/form2/formulaire_get.aspx?rdMarie=oui&C1=un&C2=deux&txtSaisie=programmation+asp.net&txtMdp=unMotDePasse&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web%0D%0A&cmbValeurs=3&lstSimple=1&lstMultiple=2&lstMultiple=4&btnEnvoyer=Envoyer&secret=uneValeur
Possiamo vedere che le scelte effettuate nel modulo si riflettono nell'URL. Diamo un'occhiata al 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 tratta di una richiesta HTTP molto simile a quella inviata inizialmente dal browser quando ha richiesto il documento senza passare alcun parametro. Ci sono due differenze:
I parametri del modulo sono stati aggiunti all'URL del documento nel formato ?param1=val1¶m2=val2&... | |
Il client utilizza questa intestazione HTTP per indicare l'URL del documento che stava visualizzando quando ha effettuato la richiesta |
Diamo un'occhiata più da vicino a come sono stati passati i parametri nella richiesta GET URL?param1=value1¶m2=value2&... HTTP/1.1, dove i parametri sono i nomi dei controlli del modulo web e i valori sono quelli ad essi associati. Di seguito è riportata una tabella a tre colonne:
- Colonna 1: mostra la definizione di un controllo HTML dall'esempio
- Colonna 2: mostra come questo controllo appare in un browser
- Colonna 3: mostra il valore inviato al server dal browser per il controllo nella Colonna 1 nella forma che assume nella richiesta GET dell'esempio
Controllo HTML | Visualizzazione pre-convalida | Valori restituiti |
<input type="radio" value="yes" name="rdMarie" />Sì <input type="radio" checked value="no" name="rdMarie" />No | - 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 di controllo selezionate dall'utente | |
<input type="text" maxlength="30" value="alcune parole" name="txtInput" /> | txtSaisie=programmazione+asp.net - testo digitato dall'utente nel . Gli spazi sono stati sostituiti con il segno + | |
<input type="password" maxlength="12" size="12" value="aPassword" name="txtMdp" /> | txtMdp="thisIsSecret" - testo digitato dall'utente nel . Il testo effettivamente digitato era "thisIsSecret". L'ultimo carattere è andato perduto perché l'attributo maxlength="12" ha limitato il numero di a 12. | |
<textarea name="areaSaisie"> riga1 riga2</textarea> | ![]() | areaSaisie=le+nozioni+di+base+di+ la%0D%0A programmazione+web - testo digitato dall'utente nel . %OD%OA è il . Gli spazi sono stati sostituiti con il segno + |
<select name="cmbValeurs"> <option value="1">scelta1 </option> <option value="2" selected>opzione2 </option> <option value="3">opzione3 </option> </select> | cmbValues=3 - valore selezionato dall'utente dall' elenco a selezione singola | |
<select size="3" name="lstSimple"> <option value="1" selected>list1</option> <option value="2">elenco2 </option> <option value="3">elenco3 </option> <option value="4">elenco4 </option> <option value="5">elenco5 </option> </select> | ![]() | lstSimple=3 - valore selezionato dall'utente dall' 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 elenco a selezione multipla |
<input type="submit" value="Invia" name="btnSubmit" /> | btnEnvoyer=Invia - attributi name e value del pulsante utilizzato sono stati utilizzati per inviare i dati del modulo al server | |
<input type="hidden" name="secret" value="aValue" /> | secret=aValue - attributo value del campo nascosto |
Potresti chiederti cosa abbia fatto il server con i parametri che gli sono stati passati. In realtà, nulla. Una volta ricevuta la richiesta
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 passato i parametri all'URL nel documento [http://localhost/form2/formulaire_get.aspx], ovvero al documento che abbiamo creato inizialmente. Non abbiamo scritto alcun codice per recuperare ed elaborare i parametri che il client ci invia. Quindi tutto avviene come se la richiesta del client fosse semplicemente:
Ecco perché, in risposta al nostro pulsante [Submit], abbiamo ricevuto la stessa pagina ottenuta inizialmente richiedendo l'URL [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. Per farlo, copiamo il file [form_get.aspx] in [form_post.aspx] e modifichiamo solo il tag <form> in [form_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 modificare il controller [form_get.aspx.vb], quindi lo lasciamo così com'è. Richiediamo il nuovo documento tramite l'URL [http://localhost/form2/formulaire_post.aspx], compiliamo il modulo come abbiamo fatto per il metodo GET e inviamo i parametri al server utilizzando il pulsante [Submit]. Riceviamo la seguente pagina di risposta dal server:

Otteniamo quindi lo stesso risultato del metodo GET, ovvero la pagina iniziale. Notiamo una differenza: nel campo [Indirizzo] del browser, i parametri trasmessi non compaiono. Ora, diamo un'occhiata alla richiesta inviata dal client e salvata 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 client compaiono nuovi elementi:
La richiesta GET è stata sostituita da una richiesta POST. I parametri non sono più presenti nella prima riga della richiesta. Possiamo notare che ora sono posizionati dopo la richiesta HTTP, a seguito di una riga vuota. La loro codifica è identica a quella della richiesta GET. | |
numero di caratteri "pubblicati", ovvero il numero di caratteri che il server web deve leggere dopo aver ricevuto le intestazioni HTTP per recuperare il documento inviato dal client. Il documento in questione qui è 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. Un metodo è migliore dell'altro? Abbiamo visto che se i valori di un modulo fossero inviati dal browser utilizzando il metodo GET, il browser visualizzerebbe l'URL richiesto nel campo Indirizzo nel formato URL?param1=val1¶m2=val2&.... Questo può essere visto sia come un vantaggio che come uno svantaggio:
- un vantaggio se si desidera consentire all'utente di salvare questo URL parametrizzato nei propri segnalibri
- uno svantaggio se non si desidera che l'utente abbia accesso a determinate informazioni del modulo, come i campi nascosti
D'ora in poi, useremo quasi esclusivamente il metodo POST nei nostri moduli.
5.4. Elaborazione lato server dei valori dei moduli
5.4.1. Panoramica dell'esempio
Ora che abbiamo stabilito la connessione 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. Il capitolo precedente ha fornito la risposta:
- se il metodo del tag <form> è GET, i valori dei parametri verranno recuperati dalla collezione [Request.QueryString]
- Se il metodo del tag <form> è POST, i valori dei parametri "inviati" verranno recuperati dalla collezione [Request.Form]. A questo punto è necessario un chiarimento. Il tag <form> può specificare l'URL di destinazione per la richiesta GET o POST utilizzando l'attributo [action]. Questo URL può essere configurato indipendentemente dal fatto che si tratti di una richiesta GET o POST, nella forma action="url?param1=val1¶m2=val2&..". Questi parametri vengono quindi aggiunti a quelli contenuti tra i tag <form> e </form>, che saranno inviati al server tramite una richiesta GET o POST. Poiché fanno parte dell'URL di destinazione, saranno recuperati dalla raccolta [Request.QueryString] indipendentemente dal fatto che la richiesta sia di tipo GET o POST.
Ora scriveremo un'applicazione MVC con due viste:
- La prima vista è il modulo precedente. La chiameremo [form_view].
- La seconda vista è una pagina informativa che elenca i valori inseriti nella prima pagina. Un link permette all'utente di tornare al modulo. Chiameremo questa vista [view_confirmation].
La [form_view] viene inviata all'utente, che la compila e la invia. Potrebbe apparire così appena prima dell'invio:

L'utente fa clic sul pulsante [Invia] per inviare i propri dati. In cambio, riceve la seguente [validation_view]:

5.4.2. Il controller dell'applicazione
Nel capitolo precedente abbiamo visto che possiamo assegnare il ruolo di controller per un'applicazione MVC al file [global.asax], attraverso il quale passano tutte le richieste dei client. Abbiamo già presentato un'applicazione MVC costruita in questo modo e qui seguiremo il modello di sviluppo presentato in precedenza. Il file [global.asax] sarà il seguente:
Consiste in una singola riga che fa riferimento al controller situato 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)
' retrieve the action to be performed
Dim action As String
If Request.QueryString("action") Is Nothing Then
action = "init"
Else
action = Request.QueryString("action").ToString.ToLower
End If
' execute the action
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 controller funziona come segue:
- cerca una stringa di parametri contenente il parametro [action] nell'URL di destinazione. Se questo manca, si comporta come se [action=init] fosse presente nella stringa di parametri.
- Sono riconosciute solo due azioni:
- init: il modulo precompilato viene inviato al client
- validation: la pagina di conferma dei dati inseriti dall'utente viene inviata al client
- Se l'azione non è una di quelle sopra indicate, il sistema si comporta come se fosse presente [action=init]. Potrebbe anche essere restituita 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] eseguire questa operazione. 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>
Vediamo il codice HTML del modulo che abbiamo 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 si fa clic sul pulsante [Invia] verranno inviati utilizzando il metodo HTTP POST
- action: la sintassi action="url" viene utilizzata per specificare 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&... Questo è ciò che viene fatto qui, dove 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 ha fornito questo modulo. Nel nostro esempio sopra, questo indirizzo è [http://localhost/mvcform1]. Il browser effettuerà quindi una richiesta [POST /mvcform1?action=validation] alla macchina [localhost].
Sono stati aggiunti dei pulsanti per consentire all'utente di deselezionare gli elementi dagli elenchi [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 sul pulsante [Cancella] si deseleziona tutti gli elementi dell'elenco a cui è associato. Prendiamo l'esempio dell'elenco [lstMultiple]. Cliccando sul pulsante [Cancella] corrispondente si attiva l'esecuzione della funzione JavaScript [raz(lstMultiple)]. Ricordate che il codice JavaScript in un documento HTML visualizzato da un browser viene eseguito dal browser stesso, non dal server. JavaScript è un linguaggio molto completo che permette di aggiungere funzionalità dinamiche alle pagine senza l'intervento del server. La funzione [raz] è la seguente:
Questa funzione accetta un parametro che è un oggetto JavaScript che rappresenta un elenco HTML. Questo oggetto ha 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à è -1. Al contrario, impostare un valore per questa proprietà seleziona un nuovo elemento nell'elenco HTML, e impostarlo a -1 significa che nessun elemento è selezionato. Questo è ciò che viene fatto qui.
Infine, si noti che il codice di presentazione [form.aspx] non è accompagnato da un controller [form.aspx.vb]. Infatti, non vi è alcun contenuto dinamico generato dal server nel documento HTML, quindi non è necessario un controller.
5.4.4. Gestione dell'azione di convalida
Quando il controller elabora l'azione "validation", deve generare una pagina che elenchi i valori inseriti dall'utente. È compito della pagina [validation.aspx] eseguire questa operazione. Visivamente, la pagina ha questo aspetto:

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 <%=variable%> del documento vengono calcolate dal controller associato [validation.aspx.vb]:
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
'retrieve posted parameters
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
' retrieves the value of field [field] from the posted request
' anything?
If Request.Form(champ) Is Nothing Then Return ""
' retrieve the value(s) of the
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 eseguito nella procedura [Form_Load]. Il valore di un campo "pubblicato" viene ottenuto utilizzando 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 dei parametri inviati, viene restituita la stringa vuota come valore di C
- altrimenti, l'array di valori per il campo C viene ottenuto tramite [Request.Form.GetValues(C)]. Questi vengono concatenati in una stringa nella forma [val1][val2]...[valn], dove [vali] è l'i-esimo valore del campo C
Il campo [areaSaisie] viene gestito in modo speciale. Il suo valore viene inviato dal browser nella forma areaSaisie=line1\r\nline2\r\n... dove \r è il codice ASCII 13 (ritorno a capo) e \n è il codice ASCII 10 (avanzamento riga). La funzione getValue(areaSaisie) è quindi la stringa "line1\r\nline2\r\n...". Questa stringa viene suddivisa in righe utilizzando il metodo [Regex.Split]. Ciò produce un array di stringhe {line1,line2,...}. Questo array viene convertito nella stringa "line1,line2,..." utilizzando il metodo [String.Join]. È questa stringa finale che verrà visualizzata come valore del campo [areaSaisie]. L'obiettivo era quello di dimostrare come estrarre le singole righe da un campo HTML [TextArea].
5.4.5. Test
Mettiamo tutti i file (global.asax, global.asax.vb, formulaire.aspx, validation.aspx, validation.aspx.vb) in una cartella chiamata <application-path>. Avviamo il server Cassini con i parametri (<application-path>,/mvcform1). Creiamo un file [default.aspx] vuoto nella cartella <application-path>, 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 esiste. Ecco perché lo abbiamo creato. Prima di visualizzarlo, verrà eseguito lo script [global.asax] che alla fine visualizzerà la pagina [form.aspx]. Questo è il motivo per cui il file [default.aspx] può essere vuoto.
Supponiamo che il modulo convalidato sia il seguente:

Facendo clic sul pulsante [Invia] viene visualizzata la pagina seguente:

Innanzitutto, si noti l'URL di risposta: [http://localhost/mvcform1/?action=validation]. Questo è l'URL dell'attributo [action] del tag <form> nel 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" selected value="no" name="rdMarie">No | Il valore ottenuto è l'attributo [value] della casella di controllo |
C1 | a | <input type="checkbox" value="uno" name="C1">1 | uguale |
C2 | due | <input type="checkbox" selezionato value="due" name="C2">2 | uguale |
C3 | <input type="checkbox" value="three" 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] era quindi vera. | |
txtInput | Programmazione ASP.NET | <input type="text" ... name="txtSaisie"> | Il valore restituito è il testo presente nel campo di immissione al momento della convalida |
txtMdp | password | <input type="password" ...name="txtMdp"> | same |
campo di immissione | le basi della programmazione web | <textarea name="areaSaisie"> ...</textarea> | stesso |
cmbValues | 3 | <select name="cmbValues"> ... <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">list3</option> ... </select> | stesso |
lstMultiple | 2 4 | <select multiple size="3" name="lstMultiple"> ... <option value="2">multiple2 </option> ... <option value="4">multiple4 </option> ... </select> | I valori ottenuti sono quelli degli attributi [value] delle opzioni selezionate |
segreto | aValue | <input type="hidden" name="secret" value="aValue"> | Il valore ottenuto è l'attributo [value] del campo nascosto |
Ora diamo un'occhiata agli elenchi. Supponiamo che al momento della convalida lo stato del modulo sia il seguente:

- l'opzione [choice1] è selezionata nella casella combinata
- nessuna opzione è selezionata negli altri due elenchi. Abbiamo utilizzato i pulsanti [Clear] per ottenere questo risultato.
Ecco la pagina restituita dopo la convalida:

Quando non viene selezionato alcun valore in un elenco, il browser non invia un parametro corrispondente. Nel codice di [validation.aspx.vb], le espressioni [Request.Form("lstSimple")] e [Request.Form("lstMultiple")] sono quindi uguali alla costante [Nothing], da cui il risultato mostrato sopra.
5.5. Mantenimento dello stato di una pagina
5.5.1. Mantenimento dello stato di una pagina con una sessione
Duplichiamo l'intera applicazione precedente in una nuova cartella. Aggiungiamo un collegamento alla pagina [validation.aspx] che consente all'utente di tornare al modulo:

La modifica da apportare alla pagina [validation.aspx] consiste nell'aggiunta del collegamento:
.....
<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=form], che permette al server di sapere che deve visualizzare il modulo così com'era al momento dell'invio. Ciò differisce dall'azione [init], che visualizza un modulo predefinito. L'URL con il parametro [?action=form] non ha in realtà un URL. Sarà quindi lo stesso di quello che ha visualizzato la pagina di invio. Come abbiamo visto nell'esempio precedente, questo è l'URL della cartella dell'applicazione. La richiesta passerà quindi attraverso il controller. Il controller deve ora gestire l'azione [form]. Il codice in [global.asax.vb] viene modificato come segue:
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
' retrieve the action to be performed
Dim action As String
If Request.QueryString("action") Is Nothing Then
action = "init"
Else
action = Request.QueryString("action").ToString.ToLower
End If
' execute the action
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
Se l'azione è "form", inoltriamo semplicemente la richiesta alla pagina [form.aspx]. Sappiamo che questa pagina visualizza un modulo predefinito senza parti variabili. Pertanto, questa pagina non può visualizzare il modulo con i valori che aveva al momento dell'invio. Stiamo cercando di evidenziare questo punto qui. Se tutti i file dell'applicazione sono stati inseriti in <application-path>, avviamo Cassini con i parametri (<application-path>,/mvcform2) e quindi 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 [Torna al modulo] presente (ma non mostrato) nella pagina sopra. Riceviamo la seguente risposta dal server:

Notiamo che:
- l'URL richiesto ha effettivamente il parametro action=form come desiderato
- il modulo visualizzato ha perso i valori inseriti.
Sappiamo perché non riusciamo a recuperare i valori inseriti. Se guardiamo il codice del documento [form.aspx], vediamo che è tutto statico, quindi è costretto a visualizzare la stessa pagina ogni volta. È chiaro che dobbiamo rendere questo codice dinamico. Deve visualizzare i valori convalidati dall'utente. Ma dove dovremmo memorizzarli?
Ricordiamo la legge ferrea del protocollo HTTP stateless:
- Viene richiesta l'URL [http://localhost/mvcform2] e si riceve una risposta. Una connessione TCP-IP è stata aperta tra il client e il server all'inizio della richiesta e chiusa alla fine della risposta.
- L'utente inserisce e invia i dati. Viene richiesto l'URL [http://localhost/mvcform2/?action=validation] e si riceve una risposta. Viene aperta e poi chiusa una nuova connessione TCP/IP tra le due parti.
- L'utente fa clic sul collegamento [Torna al modulo]. Viene richiesto l'URL [http://localhost/mvcform2/?action=formulaire] e viene ricevuta una risposta. È stata aperta e poi chiusa una nuova connessione TCP/IP tra le due parti.
I cicli di richiesta-risposta sono indipendenti l'uno dall'altro perché ciascuno utilizza una nuova connessione TCP-IP. Quando un'applicazione client-server utilizza una singola connessione TCP-IP per una serie di scambi, il server può identificare un client tramite la sua connessione. Può quindi memorizzare informazioni che collegherà a una connessione specifica e tracciare così gli scambi. Quando gli scambi avvengono su connessioni diverse, il server non può identificare un client tramite una connessione. È necessario un altro metodo. Abbiamo introdotto uno di questi metodi nel capitolo precedente: il meccanismo di sessione. Esso consente ai cicli di richiesta-risposta di memorizzare informazioni in un oggetto [Session] accessibile a tutti i cicli successivi.
Ora che disponiamo di un'applicazione MVC con sessioni, non possiamo più utilizzare il file [global.asax] come controller, come mostrato nel capitolo precedente. Il ruolo di controller dell'applicazione deve essere gestito da una pagina specifica dedicata a questo scopo. In questo caso, sarà la pagina [main.aspx]. Procederemo come segue:
- Quando l'utente invia i propri dati (action=validation), il controller [main.aspx.vb] li memorizzerà nella sessione corrente prima di visualizzare la pagina di convalida.
- Quando il modulo deve essere visualizzato con i valori inseriti (action=form), 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 da 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
' retrieve the action to be performed
Dim action As String
If Request.QueryString("action") Is Nothing Then
action = "init"
Else
action = Request.QueryString("action").ToString.ToLower
End If
' execute the action
Select Case action
Case "init"
' the pre-filled form is displayed
Context.Items("formulaire") = initForm()
Server.Transfer("formulaire.aspx", True)
Case "validation"
' the confirmation page is displayed after saving the values posted in the session
Session.Item("formulaire") = Request.Form
Server.Transfer("validation.aspx", True)
Case "formulaire"
' displays the form with values taken from the session
Context.Items("formulaire") = Session.Item("formulaire")
Server.Transfer("formulaire.aspx", True)
Case Else
' the pre-filled form is displayed
Context.Items("formulaire") = initForm()
Server.Transfer("formulaire.aspx", True)
End Select
End Sub
Private Function initForm() As NameValueCollection
' initialize the form
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
Vediamo l'essenza della struttura del controller dell'applicazione discussa in precedenza, con le seguenti differenze:
- il lavoro del controller viene eseguito nella procedura [Form_Load]
- nel caso dell'azione [validation], i valori del modulo presenti in [Request.Form] vengono memorizzati nella sessione associata alla chiave "form". L'esecuzione viene quindi trasferita alla pagina [validation.aspx], che visualizzerà questi valori.
- Per le altre azioni, l'esecuzione viene trasferita in tutti i casi alla pagina [formulaire.aspx]. Questa pagina si aspetta una chiave "formulaire" nel proprio contesto, che sarà associata a un oggetto di tipo [Request.Form], ovvero di tipo [NameValueCollection]. Questo oggetto deve contenere la raccolta dei valori per i campi del modulo.
- Se l'azione è [init] o un'azione non riconosciuta, la raccolta di valori viene costruita arbitrariamente dalla funzione [initForm].
- Se l'azione è [form], questa raccolta è la raccolta [Request.Form] che è stata inserita nella sessione dall'azione [validation]
5.5.3. Il nuovo modulo
Poiché l'applicazione non visualizza più lo stesso contenuto nel modulo, questo deve essere generato dinamicamente. La nuova pagina [form.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 [yes] deve essere selezionato, altrimenti il valore "" | |
lo stesso vale per il pulsante di opzione [no] | |
lo stesso vale per la casella di controllo [C1] | |
lo stesso per la casella di controllo [C2] | |
lo stesso per la casella di controllo [C3] | |
il testo da inserire nel campo [txtInput] | |
il testo da inserire nel campo [txtPassword] | |
il testo da inserire nel campo [areaInput] | |
il testo HTML per le opzioni nell'elenco a discesa [cmbValeurs] | |
il testo HTML delle opzioni nell'elenco a discesa [lstSimple] | |
il testo HTML delle opzioni nell'elenco a discesa [lstMultiple] | |
I valori di queste variabili sono calcolati dal controller della pagina [formulaire.aspx.vb]:
Imports Microsoft.VisualBasic
Imports System.Collections.Specialized
Public Class formulaire
Inherits System.Web.UI.Page
' constant form fields
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"}
' dynamic form fields
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
' retrieve the previous request from the session
Dim form As NameValueCollection
If Not Context.Items("formulaire") Is Nothing Then
form = Context.Items("formulaire")
Else
form = New NameValueCollection
End If
' prepare the page to be displayed
' radio buttons
rdouichecked = ""
rdnonchecked = "checked"
If isEqual(form("rdMarie"), "oui") Then
rdouichecked = "checked"
rdnonchecked = ""
End If
' checkboxes
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"
' input fields
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
' lists
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
' renders HTML code for <select> tag options
' values: table of tag option values
' labels: table of tag option labels
' selections: options to select
Dim iValeur As Integer
Dim iSelection As Integer
Dim selected As String
Dim toString As String = ""
' browse the list of option values
For iValeur = 0 To valeurs.Length - 1
' check whether the current value should be selected
selected = "" : iSelection = 0
Do While iSelection < sélections.Length And selected = ""
If valeurs(iValeur) = sélections(iSelection) Then selected = "selected"
iSelection += 1
Loop
' we integrate the HTML code from the
toString += "<option " + selected + " value='" + valeurs(iValeur) + "'> " _
+ libelles(iValeur) + "</option>" + ControlChars.CrLf
Next
' we return the result
Return toString
End Function
Private Function isEqual(Byval champ As Object, ByVal valeur As String) As Boolean
' returns true if field is equal to value
If champ Is Nothing OrElse champ.ToString <> valeur Then
Return false
Else
Return true
End If
end function
End Class
Quando la pagina [form.aspx] inizia a essere eseguita, troverà nel proprio contesto una chiave "form" associata alla raccolta dei valori dei campi che deve visualizzare.
' retrieve the previous request from the session
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é controlliamo se [Context.Items("form")] esiste. In realtà, il controller assegna un valore a questo oggetto in tutti i casi. Tuttavia, nulla impedisce al client di richiedere direttamente la pagina [form.aspx] senza passare attraverso il controller. Se così fosse, il codice precedente funzionerebbe con una raccolta di valori vuota, ma non ci sarebbe alcun "crash".
Il codice esegue un'iterazione attraverso la raccolta di valori ricevuta per calcolare tutte le variabili dinamiche della pagina HTML associata. Sebbene sia lungo, questo codice non è particolarmente complicato e lasceremo al lettore il compito di esplorarlo per non appesantire questa spiegazione. Ci concentreremo, tuttavia, su come generare il codice HTML per i tre elenchi [select]. Questo codice è generato dalla seguente funzione:
Private Function getOptions(ByRef valeurs() As String, ByRef libelles() As String, ByRef sélections() As String) As String
' renders HTML code for <select> tag options
' values: table of tag option values
' labels: table of tag option labels
' selections: options to select
Dim iValeur As Integer
Dim iSelection As Integer
Dim selected As String
Dim toString As String = ""
' browse the list of option values
For iValeur = 0 To valeurs.Length - 1
' check whether the current value should be selected
selected = "" : iSelection = 0
Do While iSelection < sélections.Length And selected = ""
If valeurs(iValeur) = sélections(iSelection) Then selected = "selected"
iSelection += 1
Loop
' we integrate the HTML code of the
toString += "<option " + selected + " value='" + valeurs(iValeur) + "'> " _
+ libelles(iValeur) + "</option>" + ControlChars.CrLf
Next
' we return the result
Return toString
End Function
Si noti che le opzioni di un tag <select> corrispondono al seguente codice HTML:
Per ogni opzione, ci sono quindi tre informazioni da generare:
- 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 ogni opzione, la funzione [getOptions] riceve tre valori:
- l'array dei valori delle opzioni in [values]
- l'array dei testi delle opzioni in [labels]
- l'array dei valori da selezionare in [selections]
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
'retrieve posted parameters
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")
' save them in the session
'Session("formulaire") = Request.Form
End Sub
Private Function getValue(ByVal champ As String) As String
' retrieves the value of field [field] from the posted request
' anything?
If Request.Form(champ) Is Nothing Then Return ""
' retrieve the value(s) of the
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. Test
I file [main.aspx, main.aspx.vb, form.aspx, form.aspx.vb, validation.aspx, validation.aspx.vb] vengono collocati in <percorso-applicazione> e Casini viene avviato con i parametri (<percorso-applicazione>,/mvcform3). Richiediamo quindi l'URL [http://localhost/mvcform3/main.aspx]. Otteniamo il modulo pre-inizializzato:

Compiliamo il modulo come segue:

Facciamo clic sul pulsante [Invia] in alto. Riceviamo la seguente risposta dal server:

Utilizziamo il link [Back to form] in alto per tornare al modulo. Riceviamo la seguente nuova risposta:

Vediamo il modulo esattamente come lo abbiamo inviato.
5.5.6. Conclusione
L'esempio precedente ci ha mostrato che è possibile mantenere lo stato di una pagina durante i cicli di richiesta-risposta tra il client e il server. Tuttavia, non si tratta di un compito banale. Vedremo in un capitolo successivo che con ASP.NET è possibile fare in modo che sia il server stesso a ripristinare lo stato di una pagina.



