5. Управління користувацьким інтерфейсом
5.1. Introduction
У веб-взаємодії «клієнт-сервер» клієнт передає інформацію на сервер у вигляді ланцюжка параметрів [param1=val1¶m2=val2&...]. У наших попередніх прикладах ми найчастіше створювали цей ланцюжок вручну, використовуючи URL-адреси у форматі [http://localhost/appli? param1=val1¶m2=val2&...]. Насправді інформація, яку клієнт передає серверу, походить із форм, заповнених користувачем. У цьому розділі ми розглянемо, як їх створювати. Ми також познайомимося з інструментом WebMatrix, який дозволить нам проектувати користувацькі інтерфейси. Процес встановлення цього інструменту описано в додатках.
5.2. Мова HTML
5.2.1. Приклад
Розглянемо наступний приклад, створений за допомогою [Web Matrix], який містить:
- таблицю
- зображення
- посилання

Запустимо [WebMatrix], а потім виберемо опцію [File/New File]:

Ми вирішили створити сторінку HTML. Наведені вище дані створять файл [d:\data\devel\aspnet\chap4\exemple1\exemple1.htm]. [WebMatrix] пропонує два варіанти редагування цього файлу: режим [Design] та режим [HTML]:

Режим [Design] дозволяє використовувати палітру компонентів HTML, запропоновану [WebMatrix]:

Щоб вставити елемент із цієї палітри, достатньо двічі клацнути на ньому, а потім розмістити його у вікні [Design]. Режим [HTML] дозволяє створювати документ HTML за допомогою текстового редактора. Для цього необхідно знати синтаксис мови HTML. На вкладці [HTML] було згенеровано каркас документа:

Вікно [HTML] дуже корисне для тих, хто не знає мови HTML. Користувач створює свій документ у вікні [Design] і перевіряє код HTML, згенерований у вікні [HTML]. Таким чином користувач поступово опановує HTML і досить швидко може працювати виключно з текстовим редактором без допомоги режиму [Design]. Тепер ми покажемо, як створити документ HTML, представлений на початку цього розділу. Ми працюємо у вікні [Design]. Спочатку ми вводимо безпосередньо перший рядок тексту:

- додаємо компонент [Horizontal Rule] з палітри компонентів:

- додаємо компонент [Table]:

- поміщаємо курсор у третій рядок таблиці, щоб видалити його за допомогою опції [HTML/Edit Table/Delete Table Row]. Потім вводимо потрібний текст у кожну комірку:

- ми розміщуємо курсор в одній із комірок таблиці та переглядаємо її властивості. Вікно властивостей відображається внизу праворуч робочого середовища:

- клітинка представлена тегом HTML <TD>. Отже, нам показуються властивості тегу <TD>. Ми звертаємо увагу на таблицю, яка є об’єктом, що охоплює клітинку. Ми клацаємо на випадаючому списку (click to see parent HTML elements) вище, щоб вибрати об’єкт <TABLE>:

- об’єкт <TABLE> має властивість [border], яка визначає ширину межі навколо комірок таблиці. Тут ми вибираємо border=1.

- тепер редагуємо атрибути об’єкта <TD> комірки (1,2), щоб встановити значення align=Center та width=200 (пікселів). Текст буде вирівняно по центру в комірці (align=center), а її ширина становитиме 200 пікселів. Щоб побачити зміни, іноді доводиться вибрати вкладку [HTML], а потім повернутися до вкладки [Design]:

- тепер розмістимо текст, що передує зображенню:

- потім зображення, двічі клацнувши на компоненті [image] у палітрі:

- вибираємо зображення, щоб редагувати його властивості:

- у атрибуті [src] вводимо ім’я файлу, що містить зображення, у даному випадку [univ01.gif]:

- вводимо текст, що передує посиланню:

- перетворюємо текст [ici] на посилання на URL-адресу [http://istia.univ-angers.fr]. Для цього виділяємо його, а потім вибираємо опцію [HTML/Insert Hyperlink]:

- отримуємо такий результат:

- ми майже досягли мети. Давайте подивимося на код HTML, згенерований у вкладці [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>
Нам залишилося доопрацювати кілька деталей. Перш за все, ми хотіли б надати назву нашому документу. [WebMatrix] не дозволяє зробити це в режимі [Design]. На вкладці [HTML] замінюємо послідовність <head>..</head> на таку:
Крім того, ми хотіли б, щоб текст [Le langage HTML - 1] відображався більшим шрифтом. Послідовність <Hi>текст</Hi> дозволяє задати розмір тексту, де i може приймати значення від 1 до 6 — від найбільшого до найменшого. У цьому випадку ми виберемо H2. Послідовність
перетворюється на:
Вікно [Design] відображає наші зміни:

Залишилося лише провести тестування за допомогою опції [View/Start] або [F5]. Опція [WebMatrix] вимагає введення деяких даних для запуску веб-сервера [Cassini]:

Ми можемо прийняти значення, запропоновані за замовчуванням. Сервер [Cassini] запущено, і наша сторінка відображається у браузері:

З цікавості ми можемо перевірити, з якими параметрами було запущено [Cassini]:

Ми розглянули основи створення сторінки HTML за допомогою [WebMatrix]. Пропонуємо читачеві створити інші сторінки HTML і щоразу перевіряти згенерований код HTML. Поступово читач зможе створювати сторінки без допомоги режиму [Design]. Документ HTML має такий загальний вигляд:
Весь документ обмежений тегами <html>...</html>. Він складається з двох частин:
<head>...</head>: це невидима частина документа. Вона надає інформацію браузеру, який буде відображати документ. У ній часто зустрічається тег <title>...</title>, який визначає текст, що відображатиметься у рядку заголовка браузера. Також тут можуть бути інші теги, зокрема ті, що визначають ключові слова документа, які згодом використовуються пошуковими системами. У цій частині також можуть міститися скрипти, найчастіше написані на JavaScript або VBScript, які будуть виконуватися браузером.
<body атрибути>...</body>: це частина, яка відображатиметься браузером. Теги HTML, що містяться в цій частині, вказують браузеру «бажаний» візуальний вигляд документа. Кожен браузер інтерпретує ці теги по-своєму. Тому два браузери можуть по-різному відображати один і той самий веб-документ. Зазвичай це є однією з головних проблем веб-дизайнерів.
Код HTML попереднього документа був таким:
<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 |
<title>HTML1</title> HTML1 з’явиться в рядку заголовка браузера, який відображатиме документ | |
<hr>: відображає горизонтальну лінію | |
<атрибути таблиці>....</table>: для визначення таблиці <tr атрибути>...</tr>: для визначення рядка <td атрибути>...</td>: для визначення комірки приклади: <table border="1">...</table>: атрибут border визначає товщину межі таблиці <td align="center" width="200">комірка(1,2)</td>: визначає комірку, вміст якої буде cellule(1,2). Цей вміст буде вирівняно по горизонталі (align="center"). Ширина комірки становитиме 200 пікселів (width="200") | |
<img src="univ01.gif" />: визначає зображення, вихідний файл якого — univ01.gif — знаходиться на веб-сервері (src="univ01.gif"). Це посилання міститься у веб-документі, отриманому за допомогою URL http://localhost/exemple1.htm. Отже, браузер звернеться до URL http://localhost/univ01.gif, щоб отримати зображення, на яке тут є посилання. | |
<a href="http://istia.univ-angers.fr">тут</a>: робить текст ici посиланням на URL http://istia.univ-angers.fr. |
З цього простого прикладу видно, що для побудови всього документа браузер повинен надіслати два запити на сервер:
http://localhost/exemple1.htm, щоб отримати вихідний код HTML документа
http://localhost/univ01.gif — для отримання зображення univ01.gif
5.2.2. Створення форми
Форма HTML призначена для того, щоб представити користувачеві сторінку введення інформації, аналогічну формам введення, з якими можна зустрітися в Windows. Форма введення надсилається браузеру у вигляді документа HTML. Браузер відобразить форму користувачеві, який заповнить її та підтвердить натисканням відповідної кнопки. Після цього браузер передасть введені значення на сервер для обробки. Як ми побачимо, він надсилає на сервер не всю форму, а лише введені значення. Наступний приклад демонструє веб-форму, також створену за допомогою WebMatrix:

Код HTML, згенерований [WebMatrix], має такий вигляд:
<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>
Відповідність візуального елемента <--> тегу HTML така:
Перевірка | тег HTML |
<form name="formulaire" method="post"> | |
<input type="text" maxlength="30" value="кілька слів" name="txtSaisie" /> | |
<input type="password" maxlength="12" size="12" value="unMotDePasse" name="txtMdp" /> | |
<textarea name="areaSaisie">рядок1 рядок 2</textarea> | |
<input type="radio" value="так" name="rdMarie" />Так <input type="radio" checked value="ні" name="rdMarie" />Ні | |
<input type="checkbox" value="один" name="C1" />1 <input type="checkbox" checked value="два" name="C2" />2 <input type="checkbox" value="три" name="C3" />3 | |
<select name="cmbValeurs"> <option value="1">варіант1</option> <option value="2" selected>варіант 2</option> <option value="3">варіант 3</option> </select> | |
<select size="3" name="lstSimple"> <option value="1" selected>список1</option> <option value="2">список2</option> <option value="3">список3</option> <option value="4">список4</option> <option value="5">список5</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="Надіслати" name="btnEnvoyer" /> | |
<input type="reset" value="Скинути" name="btnRetablir" runat="server" /> | |
<input onclick="effacer()" type="button" value="Очистити" name="btnEffacer" /> |
Давайте розглянемо ці різні елементи управління.
5.2.2.1. Форма
<form name="formulaire" method="post"> |
<form name="..." method="..." action="...">...</form> | |
name="frmexemple": ім'я форми method="..." : метод, який використовує браузер для надсилання на веб-сервер значень, зібраних у формі action="..." : URL, на яку будуть надіслані значення, зібрані у формі. Веб-форма оточена тегами <form>...</form>. Форма може мати ім’я (name="xx"). Це стосується всіх елементів управління, які можна знайти у формі. Це ім’я є корисним, якщо веб-документ містить скрипти, які повинні посилатися на елементи форми. Мета форми — зібрати інформацію, введену користувачем за допомогою клавіатури/миші, та надіслати її на веб-сервер URL. Який саме? Той, що вказаний в атрибуті action="URL". Якщо цей атрибут відсутній, інформація буде надіслана на сервер, на якому розміщений документ, у якому знаходиться форма. Як веб-клієнт передає інформацію (ту, що міститься у формі) на веб-сервер? Ми вже детально розглядали це. Він може використовувати два різні методи, які називаються POST та GET. Атрибут method="méthode", у якому метод дорівнює GET або POST, тегу <form> вказує браузеру, який метод слід використовувати для надсилання інформації, зібраної у формі, на URL, вказаний атрибутом action="URL". Якщо атрибут method не вказано, за замовчуванням використовується метод GET. |
5.2.2.2. Поле введення

<input type="text" maxlength="30" value="кілька слів" name="txtSaisie" /> <input type="password" maxlength="12" size="12" value="unMotDePasse" name="txtMdp" /> |
<input type="..." name="..." size=".." value=".."> Тег input використовується для різних елементів управління. Саме атрибут type дозволяє розрізняти ці різні елементи управління між собою. | |
type="text": вказує, що це поле введення type="password": символи у полі введення замінюються на символи *. Це єдина відмінність від звичайного поля введення. Цей тип елемента управління підходить для введення паролів. size="12": кількість символів, що відображаються у полі — не обмежує введення більшої кількості символів maxlength="30": встановлює максимальну кількість символів на 30 — браузер відповідає за дотримання цього атрибута name="txtSaisie": ім’я елемента управління value="кілька слів": текст, який відображатиметься у полі введення. |
5.2.2.3. Багаторядкове поле введення

<textarea name="areaSaisie">рядок1 рядок 2</textarea> |
<textarea ...>текст</textarea> відображає багаторядковий поле введення, яке спочатку містить текст | |
rows="2": кількість рядків cols="'20" : кількість стовпців name="areaSaisie": ім'я елемента управління |
5.2.2.4. Радіо-кнопки
![]()
<input type="radio" value="так" name="rdMarie" />Так <input type="radio" checked value="ні" name="rdMarie" />Ні |
<input type="radio" атрибут2="значення2" ..../>текст відображає перемикач із текстом поруч. | |
name="rdMarie" : ім'я елемента управління. Перемикачі з однаковим ім'ям утворюють групу, елементи якої взаємовиключні: можна вибрати лише один із них. value="значення": значення, яке присвоюється перемикачу. Не слід плутати це значення з текстом, що відображається поруч із перемикачем. Останній призначений лише для відображення. checked: якщо цей ключовий параметр присутній, перемикач позначений як вибраний, інакше — ні. |
5.2.2.5. Позначки
<input type="checkbox" value="один" name="C1" />1 <input type="checkbox" checked value="два" name="C2" />2 <input type="checkbox" value="три" name="C3" />3 |
![]()
<input type="checkbox" attribut2="valeur2" ..../>текст відображає прапорець із текстом поруч. | |
name="C1": ім'я елемента управління. Поля для позначення можуть мати однакове ім'я або ні. Поля з однаковим ім'ям утворюють групу пов'язаних полів. value="значення": значення, присвоєне прапорцю. Не слід плутати це значення з текстом, що відображається поруч із перемикачем. Останній призначений лише для відображення. checked: якщо цей ключовий параметр присутній, перемикач позначений, інакше — ні. |
5.2.2.6. Список, що розгортається (комбо)
<select name="cmbValeurs"> <option value="1">варіант1</option> <option value="2" selected>варіант 2</option> <option value="3">варіант 3</option> </select> |
![]()
<select size=".." name=".."> <option [selected="selected"] [value="valeur"]>текст</option> ... </select> відображає у списку тексти, що містяться між тегами <option>...</option> | |
name="cmbValeurs": ім'я елемента управління. size="1": кількість видимих елементів списку. size="1" перетворює список на комбінований список. Це значення за замовчуванням, якщо атрибут [size] відсутній. selected="selected": якщо цей атрибут присутній для елемента списку, він відображається у списку як вибраний. У нашому прикладі вище елемент списку choix2 відображається як вибраний елемент комбінованого списку, коли той з’являється на екрані вперше. value="значення": встановлює значення, яке буде надіслано на сервер, якщо елемент вибрано. Якщо цей атрибут відсутній, на сервер надсилається текст, пов’язаний із цим елементом. |
5.2.2.7. Список з одним вибором
<select size="3" name="lstSimple"> <option value="1" selected>список1</option> <option value="2">список2</option> <option value="3">список3</option> <option value="4">список4</option> <option value="5">список5</option> </select> |

<select size=".." name=".."> <option [selected] [value="valeur"]>...</option> ... </select> відображає у списку тексти, що містяться між тегами <option>...</option> | |
ті самі, що й для випадаючого списку, який відображає лише один елемент. Цей елемент управління відрізняється від попереднього випадаючого списку лише атрибутом size>1. |
5.2.2.8. Список із можливістю множинного вибору
<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> відображає у списку тексти, що містяться між тегами <option>...</option> | |
multiple: дозволяє вибрати кілька елементів зі списку. У наведеному вище прикладі вибрано обидва елементи: liste1 та liste3. |
5.2.2.9. Кнопка типу button
<input onclick="effacer()" type="button" value="Стерти" name="btnEffacer" /> |
![]()
<input type="button" value="..." name="..." onclick="effacer()" ....> | |
type="button": визначає елемент управління «кнопка». Існують ще два типи кнопок: submit та reset. value="Очистити": текст, що відображається на кнопці onclick="функція()" : дозволяє визначити функцію, яка має виконуватися, коли користувач натискає на кнопку. Ця функція є частиною скриптів, визначених у відображеному веб-документі. Наведений вище синтаксис відповідає синтаксису javascript. Якщо скрипти написані на VBScript, слід вказати onclick="функція" без дужок. Синтаксис залишається таким самим, якщо потрібно передати параметри до функції: onclick="функція(val1, val2,...)" У нашому прикладі клік на кнопку Effacer викликає таку функцію JavaScript effacer: Функція effacer відображає повідомлення: ![]() |
5.2.2.10. Кнопка типу «submit»
<input type="submit" value="Надіслати" name="btnEnvoyer" /> |
![]()
<input type="submit" value="Надіслати" name="btnEnvoyer"> | |
type="submit": визначає кнопку як кнопку для надсилання даних форми на веб-сервер. Коли клієнт натисне на цю кнопку, браузер надішле дані форми на URL, визначений в атрибуті action тегу <form>, відповідно до методу, визначеного атрибутом method цього ж тегу. value="Відправити": текст, що відображається на кнопці |
5.2.2.11. Кнопка типу «reset»
<input type="reset" value="Скинути" name="btnRetablir" runat="server" /> |
![]()
<input type="reset" value="Скинути" name=" btnRetablir "> | |
type="reset": визначає кнопку як кнопку скидання форми. Коли клієнт натисне на цю кнопку, браузер поверне форму до того стану, в якому він її отримав. value="Скинути": текст, що відображається на кнопці |
5.2.2.12. Приховане поле
<input type="hidden" name="secret" value="uneValeur" /> |
<input type="hidden" name="..." value="..."> | |
type="hidden": вказує, що це приховане поле. Приховане поле є частиною форми, але не відображається користувачеві. Однак, якщо користувач попросить свій браузер показати вихідний код, він побачить тег <input type="hidden" value="..."> і, отже, значення прихованого поля. value="uneValeur": значення прихованого поля. У чому полягає користь прихованого поля? Воно дозволяє веб-серверу зберігати інформацію під час послідовних запитів клієнта. Розглянемо приклад веб-додатку для покупок. Клієнт купує перший товар art1 у кількості q1 на першій сторінці каталогу, а потім переходить на нову сторінку каталогу. Щоб запам’ятати, що клієнт придбав q1 товарів у кількості art1, сервер може помістити ці дві інформації в приховане поле веб-форми на новій сторінці. На цій новій сторінці клієнт купує товари q2 та art2. Коли дані цієї другої форми будуть надіслані на сервер (submit), сервер отримає не тільки інформацію (q2, art2), а й (q1, art1), яка також є частиною форми як приховане поле, яке користувач не може змінювати. Потім веб-сервер помістить у нове приховане поле дані (q1,art1) та (q2,art2) і надішле нову сторінку каталогу. І так далі. |
5.3. Передача значень форми з браузера на веб-сервер
З попереднього розділу ми вже знаємо, як клієнт передає інформацію на сервер. Він робить це за допомогою:
- запит HTTP GET url?param1=va1¶m2=val2&....
- запит HTT POST url, за яким слідує документ, що містить рядок параметрів param1=va1¶m2=val2&....
Браузер використовуватиме один із цих двох методів залежно від того, чи атрибут [method] тегу [form] має значення GET чи POST. Саме це ми й продемонструємо зараз. Сторінка, яку ми розглядали раніше, є статичною. Щоб отримати доступ до заголовків HTTP, надісланих браузером, який запитує цей документ, ми перетворюємо її на динамічну сторінку для веб-сервера .NET (IIS або Cassini). Попередній статичний код розміщується у файлі [formulaire_get.aspx], і його вміст є таким:
<%@ 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>
Наведена вище сторінка презентації пов’язана з контролером [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
' зберігає поточну запит у request.txt у папці сторінки
Dim requestFileName As String = Me.MapPath(Me.TemplateSourceDirectory) + "\request.txt"
Me.Request.SaveAs(requestFileName, True)
End Sub
End Class
При кожному виклику документа [formulaire_get.aspx] запит клієнта буде збережено у файлі [request.txt] за допомогою процедури Page_Init. Ми вже стикалися з таким режимом роботи, тому не будемо детально коментувати цей контролер.
5.3.1. Метод GET
Проведемо перший тест, у якому в коді HTML документа тег FORM визначено таким чином:
<form name="formulaire" method="get">
Ми розміщуємо файли [formulaire_get.aspx] та [formulaire_get.aspx.vb] у папці <application-path> і запускаємо сервер Cassini з параметрами (<application-path>,/form2). Викликаємо URL-адресу http://localhost/form2/formulaire_get.aspx:

Браузер щойно надіслав запит, і ми знаємо, що він було збережено у файлі [request.txt]. Давайте подивимося на його вміст:
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
Браузер використав запит HTTP GET для запиту URL-адреси [http://localhost/form2/formulaire_get.aspx]. Це завжди відбувається, коли URL-адреса вказується користувачем. Ми заповнюємо форму наступним чином:

Ми використовуємо кнопку [Envoyer], показану вище. Її код HTML такий:
При натисканні кнопки типу [Submit] браузер надсилає параметри форми (тег <form>) на URL, вказаний в атрибуті [action] тегу <form action="URL">, якщо він існує. Якщо цей атрибут відсутній, параметри форми надсилаються на URL, який вивів форму. Саме так і відбувається в даному випадку. Отже, натискання кнопки [Envoyer] має призвести до надсилання браузером запиту до URL [http://localhost/form2/formulaire_get.aspx] із передачею параметрів форми. Оскільки сторінка [formulaire_get.aspx] запам’ятовує отриманий запит, ми маємо дізнатися, як клієнт передав ці параметри. Спробуємо. Натискаємо кнопку [Envoyer]. Отримуємо таку відповідь від браузера:

Це початкова сторінка, але можна помітити, що значення URL у полі [Adresse] браузера змінилося. Воно стало таким:
http://localhost/form2/formulaire_get.aspx?rdMarie=так&C1=один&C2=два&txtSaisie=програмування+asp.net&txtMdp=unMotDePasse&areaSaisie=основи+0D%0Aвеб-програмування%0D%0A&cmbValeurs=3&lstSimple=1&lstMultiple=2&lstMultiple=4&btnEnvoyer=Надіслати&secret=uneValeur
Можна побачити, що вибір, зроблений у формі, відображається у URL. Давайте розглянемо вміст файлу [request.txt], який зберіг запит клієнта:
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
Ми бачимо запит HTTP, який досить схожий на той, що спочатку надсилав браузер, коли запитував документ без передачі параметрів. Є дві відмінності:
Параметри форми були додані після URL документа у вигляді ?param1=val1¶m2=val2&... | |
за допомогою цього заголовка HTTP клієнт вказує код URL документа, який він переглядав під час надсилання запиту |
Давайте детальніше розглянемо, як параметри були передані в запиті GET URL?param1=значення1¶m2=значення2&... HTTP/1.1, де parami — це імена елементів управління веб-форми, а valeuri — значення, пов’язані з ними. Нижче наведено таблицю з трьома стовпцями:
- 1-й стовпець: містить визначення елемента управління HTML із прикладу
- 2-й стовпець: відображення цього елемента управління в браузері
- 3-й стовпець: містить значення, яке браузер надсилає на сервер для елемента управління зі 1-го стовпця у тому вигляді, в якому воно міститься у запиті GET з прикладу
елемент управління HTML | зображення до підтвердження | повернуте значення (значення) |
<input type="radio" value="oui" name="rdMarie" />Так <input type="radio" checked value="ні" name="rdMarie" />Ні | rdMarie=так - значення атрибута value кнопки радіо-кнопки, яку вибрав користувач. | |
<input type="checkbox" value="un" name="C1" />1 <input type="checkbox" checked value="два" name="C2" />2 <input type="checkbox" value="три" name="C3" />3 | C1=один C2=два - значення атрибутів value полів , позначених користувачем | |
<input type="text" maxlength="30" value="деякі слів" name="txtSaisie" /> | txtSaisie=програмування+asp.net - текст, введений користувачем у поле введення. Пробіли замінено знаком + | |
<input type="password" maxlength="12" size="12" value="пароль" name="txtMdp" /> | txtMdp=цеСекрет - текст, введений користувачем у поле введення. Фактично введений текст був "цесекрет". Останній символ було втрачено, оскільки атрибут maxlength="12" обмежував кількість символів до 12. | |
<textarea name="areaSaisie"> рядок1 рядок2</textarea> | ![]() | areaSaisie=основи+ la%0D%0A веб-програмування+ — текст, введений користувачем у поле введення. %OD%OA — це позначка кінця рядка. Пробіли були замінені на знак + |
<select name="cmbValeurs"> <option value="1">варіант1 </option> <option value="2" selected>варіант 2 </option> <option value="3">варіант 3 </option> </select> | cmbValeurs=3 - значення, обране користувачем у списку з одним варіантом вибору | |
<select size="3" name="lstSimple"> <option value="1" selected>список1</option> <option value="2">список2 </option> <option value="3">список3 </option> <option value="4">список4 </option> <option value="5">список 5 </option> </select> | ![]() | lstSimple=3 - значення, обране користувачем у списку з одним варіантом вибору |
<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 - значення, вибрані користувачем у списку з можливістю множинного вибору |
<input type="submit" value="Надіслати" name="btnEnvoyer" /> | btnEnvoyer=Надіслати - ім'я та атрибут value кнопки, яка використовувалася для надсилання даних форми на сервер | |
<input type="hidden" name="secret" value="uneValeur" /> | secret=uneValeur - атрибут value прихованого поля |
Можна запитати, що сервер зробив із параметрами, які йому передали. Насправді нічого. Після отримання команди
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
веб-сервер передав параметри до URL у документ [http://localhost/form2/formulaire_get.aspx], c.a.d. у документ, який ми створили спочатку. Ми не писали жодного коду для отримання та обробки параметрів, які надсилає нам клієнт. Тому все відбувається так, ніби запит клієнта був просто таким:
Саме з цієї причини у відповідь на натискання нашої кнопки [Envoyer] ми отримали ту саму сторінку, що й спочатку при запиті URL [http://localhost/form2/formulaire_get.aspx] без параметрів.
5.3.2. Метод POST
Документ HTML тепер налаштований так, щоб браузер використовував метод POST для надсилання значень форми на веб-сервер. Для цього ми копіюємо файл [formulaire_get.aspx] у [formulaire_post.aspx] і змінюємо лише тег <form> у [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">
Немає необхідності змінювати контролер [formulaire_get.aspx.vb], тому залишаємо його без змін. Запитуємо новий документ через URL [http://localhost/form2/formulaire_post.aspx], заповнюємо форму так само, як для методу GET, і передаємо параметри на сервер за допомогою кнопки [Envoyer]. Ми отримуємо від сервера таку сторінку відповіді:

Отже, ми отримуємо той самий результат, що й у методах GET та c.a.d — початкову сторінку. Можна помітити одну відмінність: у полі [Adresse] браузера передані параметри не відображаються. Тепер розглянемо запит, надісланий клієнтом і збережений у файлі [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
У запиті клієнта HTTP з'являються нові елементи:
запит GET замінено на запит POST. Параметри більше не містяться в першому рядку запиту. Можна помітити, що тепер вони розміщені після запиту HTTP, після порожнього рядка. Їхнє кодування ідентичне тому, яке вони мали в запиті GET. | |
кількість «відправлених» символів, c.a.d. Кількість символів, яку веб-сервер повинен прочитати після отримання заголовків HTTP, щоб отримати документ, який надсилає йому клієнт. У даному випадку цим документом є список значень форми. | |
вказує тип документа, який клієнт надішле після заголовків HTTP. Тип [application/x-www-form-urlencoded] вказує, що це документ, який містить значення форми. |
Існує два методи передачі даних на веб-сервер: GET та POST. Чи є один із цих методів кращим за інший? Ми бачили, що якщо значення форми надсилалися браузером за допомогою методу GET, браузер відображав у своєму полі Adresse запитуване значення URL у формі URL?param1=val1¶m2=val2&.... Це можна розглядати як перевагу або недолік:
- перевагою, якщо ми хочемо дозволити користувачеві додати цей налаштований URL до своїх улюблених посилань
- недолік, якщо не хочемо, щоб користувач мав доступ до певної інформації у формі, наприклад, до прихованих полів
Надалі ми будемо використовувати у своїх формах майже виключно метод POST.
5.4. Обробка значень форми на стороні сервера
5.4.1. Огляд прикладу
Тепер, коли ми встановили зв’язок між тегом HTML <form method="GET/POST" ...> та способом, яким браузер надсилає значення форми, ми знаємо, як отримати їх на стороні сервера. Відповідь ми отримали в попередньому розділі:
- якщо метод тегу <form> дорівнює GET, значення параметрів будуть отримані з колекції [Request.QueryString]
- якщо метод тегу <form> дорівнює POST, значення «відправлених» параметрів будуть отримані з колекції [Request.Form]. Тут слід зробити уточнення. Тег <form> може за допомогою атрибута [action] вказати цільову URL-адресу GET або POST. Цю URL-адресу цілком можна налаштувати незалежно від того, чи маємо ми GET, чи POST, у формі action="url?param1=val1¶m2=val2&..". Ці параметри додаються до тих, що містяться між тегами <form> та </form> і які будуть передані на сервер за допомогою GET або POST. Оскільки вони є частиною цільового URL-адреси, їх можна отримати в колекції [Request.QueryString] незалежно від того, чи маємо ми справу з GET, чи з POST.
Тепер ми напишемо додаток MVC із двома вікнами:
- перший вигляд — це попередня форма. Назвемо її [vue_formulaire].
- другий вигляд — це інформаційна сторінка, на якій перелічено значення, введені на першій сторінці. Посилання дозволяє повернутися до форми. Назвемо цей вигляд [vue_confirmation].
Вигляд [vue_formulaire] надсилається користувачеві, який його заповнює та підтверджує. Перед підтвердженням він може виглядати так:

Користувач натискає кнопку [Envoyer], щоб підтвердити введені дані. У відповідь він отримує наступний вигляд [vue_validation]:

5.4.2. Контролер додатка
У попередньому розділі ми бачили, що роль контролера додатка MVC можна доручити файлу [global.asax], через який проходять усі запити клієнтів. Ми вже розглядали додаток MVC, побудований за такою схемою, і тут дотримуємося представленої тоді моделі розробки. Файл [global.asax] матиме такий вигляд:
Він складається з єдиного рядка, що посилається на контролер, розміщений у файлі [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)
' отримуємо дію, яку потрібно виконати
Dim action As String
If Request.QueryString("action") Is Nothing Then
action = "init"
Else
action = Request.QueryString("action").ToString.ToLower
End If
' виконуємо дію
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
Принцип роботи контролера такий:
- він очікує в цільовому URL-адресі рядок параметрів, що містить параметр [action]. Якщо його немає, то система поводиться так, ніби в рядку параметрів був параметр [action=init].
- Підтримуються лише дві дії:
- init: клієнту надається попередньо заповнена форма
- validation: клієнту надається сторінка з підтвердженням введених даних
- якщо дія не є однією з перерахованих вище, то вважається, ніби в рядку параметрів був параметр [action=init]. Також можна вивести сторінку з повідомленням про помилку.
5.4.3. Обробка дії init
Коли контролер обробляє дію «init», він повинен згенерувати попередньо заповнену форму. Цю роботу виконує сторінка [formulaire.aspx]. Її код такий:
<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>
Ми бачимо код HTML з форми, яку розглядали раніше, за винятком кількох відмінностей. Код тегу <form> було змінено:
<form name="formulaire" method="post" action="?action=validation">
- post: значення, введені користувачем і надіслані на сервер при натисканні кнопки типу [submit], будуть оброблятися методом HTTP POST
- action: синтаксис action="url" використовується для вказівки URL-адреси, на яку мають бути надіслані значення форми. Ця URL-адреса може містити ланцюжок параметрів у вигляді param1=val1¶m2=val2&... Саме це робиться тут, де ми передаємо параметр [action=validation], щоб вказати контролеру, яку дію він повинен виконати. Варто зауважити, що перед цим ланцюжком параметрів не стоїть веб-адреса. Тоді браузер надішле параметри форми на адресу, яка надала йому цю форму. У нашому прикладі, наведеному вище, ця адреса — [http://localhost/mvcform1]. Отже, браузер надішле запит [POST /mvcform1?action=validation] на сервер [localhost].
Були додані кнопки, щоб користувач міг скасувати вибір елементів зі списків [lstSimple] та [lstMultiple]:

Це відображається у вигляді такого коду 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>
Натискання на кнопку [Raz] призводить до скасування виділення всіх елементів списку, з яким вона пов’язана. Розглянемо приклад списку [lstMultiple]. Клік на відповідну кнопку [Raz] призводить до виконання функції JavaScript [raz(lstMultiple)]. Нагадаємо, що код JavaScript документа HTML, який відображається браузером, виконується саме цим браузером, а не сервером. JavaScript — це дуже функціональна мова, яка дозволяє надавати сторінкам динамічний вигляд без втручання сервера. Функція [raz] має такий вигляд:
Ця функція приймає параметр у вигляді об’єкта JavaScript, що представляє список HTML. Цей об’єкт має властивості та методи. Однією з його властивостей є [selectedIndex], значенням якої є номер першого вибраного варіанта у списку HTML. Якщо такого елемента немає, значення цього властивості дорівнює -1. І навпаки, присвоєння значення цьому властивості означає вибір нового елемента зі списку HTML, а присвоєння йому значення -1 означає, що жоден елемент не вибрано. Саме це й робиться тут.
Нарешті, слід зауважити, що код представлення [formulaire.aspx] не супроводжується контролером [formulaire.aspx.vb]. Дійсно, у документі HTML немає жодної динамічної частини, згенерованої сервером, тому немає необхідності мати контролер.
5.4.4. Обробка дії «validation»
Коли контролер обробляє дію «validation», він повинен згенерувати сторінку зі списком значень, введених користувачем. Цю роботу виконує сторінка [validation.aspx]. Візуально сторінка виглядає наступним чином:

Її код HTML виглядає так:
<%@ 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>
Динамічні частини <%=variable%> документа обчислюються відповідним контролером [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
'отримуємо надіслані параметри
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
' отримує значення поля [champ] із надісланого запиту
' щось?
If Request.Form(champ) Is Nothing Then Return ""
' отримуємо значення поля або поля
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
Обчислення значень, що відображаються, виконується у процедурі [Form_Load]. Значення «опублікованого» поля отримується за допомогою функції getValue(C), де C — ім’я поля. Ключові моменти цієї функції такі:
- якщо C відсутнє у переданому ланцюжку параметрів, то як значення C повертається порожній ланцюжок
- в іншому випадку отримується масив значень поля C за допомогою [Request.Form.GetValues(C)]. Ці значення об’єднуються в символьний рядок у формі [val1][val2]...[valn], де [vali] — це значення № i поля C
Поле [areaSaisie] обробляється особливим чином. Його значення надсилається браузером у вигляді areaSaisie=рядок1\r\nрядок2\r\n... де \r — це символ з кодом ASCII 13 (повернення каретки), а \n — символ з кодом ASCII 10 (перехід на новий рядок). Отже, функція getValue(areaSaisie) — це рядок «рядок1\r\nрядок2\r\n...». Цей рядок розбивається на рядки за допомогою методу [Regex.Split]. У результаті отримуємо масив рядків {рядок1, рядок2, ...}. Цей масив перетворюється на рядок «рядок1, рядок2, ...» за допомогою методу [String.Join]. Саме цей рядок буде відображатися як значення поля [areaSaisie]. Метою цього прикладу було продемонструвати, як можна отримати окремі рядки поля HTML типу [TextArea].
5.4.5. Тестування
Ми розміщуємо всі файли (global.asax, global.asax.vb, formulaire.aspx, validation.aspx, validation.aspx.vb) у папку <application-path>. Запускаємо сервер Cassini з параметрами (<application-path>,/mvcform1). У папці <application-path> створюємо порожній файл [default.aspx], а потім звертаємося за URL-адресою [http://localhost/mvcform1]. Оскільки [/mvcform1] є віртуальним шляхом до папки, а не до документа, веб-сервер відобразить документ [default.aspx], якщо він існує. Саме тому ми його й створили. Перед його відображенням буде виконано скрипт [global.asax], що в результаті призведе до відображення сторінки [formulaire.aspx]. Саме тому файл [default.aspx] може бути порожнім.
Припустимо, що затверджена форма має такий вигляд:

Натискання кнопки [Envoyer] повертає таку сторінку:

Спочатку звернемо увагу на URL-адресу відповіді: [http://localhost/mvcform1/?action=validation]. Це URL з атрибута [action] тегу <form> форми [formulaire.aspx]:
<form name="formulaire" method="post" action="?action=validation">
Розглянемо по черзі значення, отримані для різних полів форми:
поле | значення | HTML | коментарі |
rdMarie | так | <input type="radio" value="так" name="rdMarie">Так <input type="radio" checked value="ні" name="rdMarie">Ні | отримане значення є атрибутом [value] позначеної кнопки |
C1 | один | <input type="checkbox" value="un" name="C1">1 | те саме |
C2 | два | <input type="checkbox" checked value="два" name="C2">2 | те саме |
C3 | <input type="checkbox" value="три" name="C3">3 | Ця кнопка не була відмічена користувачем. Отже, її значення не було надіслано браузером. У коді умова [Request.Form("C3") is Nothing], отже, була істинною. | |
txtSaisie | Програмування asp.net | <input type="text" ... name="txtSaisie"> | отримане значення — це текст, що міститься у полі введення на момент підтвердження |
txtMdp | mdp | <input type="password" ...name="txtMdp"> | те саме |
areaSaisie | основи веб-програмування | <textarea name="areaSaisie"> ...</textarea> | те саме |
cmbValeurs | 3 | <select name="cmbValeurs"> ... <option value="3">варіант 3</option> </select> | отримане значення є атрибутом [value] вибраної опції |
lstSimple | 3 | <select size="3" name="lstSimple"> .... <option value="3">список3</option> ... </select> | те саме |
lstMultiple | 2 4 | <select multiple size="3" name="lstMultiple"> ... <option value="2">multiple2 </option> ... <option value="4">multiple4 </option> ... </select> | отримані значення відповідають атрибутам [value] вибраних опцій |
secret | uneValeur | <input type="hidden" name="secret" value="uneValeur"> | отримане значення відповідає атрибуту [value] прихованого поля |
Тепер розглянемо списки. Припустимо, що на момент перевірки стан форми такий:

- опція [choix1] вибрана в comboBox
- у двох інших списках жодна опція не обрана. Для цього були використані кнопки [Raz].
Ось сторінка, яка з’явилася після підтвердження:

Коли в списку не вибрано жодного значення, браузер не надсилає відповідного параметра. Отже, у коді [validation.aspx.vb] вирази [Request.Form("lstSimple")] та [Request.Form("lstMultiple")] дорівнюють константі [Nothing], звідки й випливає результат, показаний вище.
5.5. Збереження стану сторінки
5.5.1. Збереження стану сторінки за допомогою сесії
Ми копіюємо весь попередній додаток у нову папку. На сторінці [validation.aspx] додаємо посилання, яке дозволяє користувачеві повернутися до форми:

Зміни, які потрібно внести на сторінці [validation.aspx], полягають у додаванні посилання:
.....
<TR>
<TD width="84">secret</TD>
<TD><%=secret%></TD>
</TR>
</TABLE>
<P>
<a href="?action=formulaire">Retour au formulaire</a>
</P>
</body>
</HTML>
Атрибут [href] посилання має значення URL-адреси з єдиним параметром [action=formulaire], що дозволяє серверу зрозуміти, що він повинен відобразити форму такою, якою вона була на момент її підтвердження. Отже, існує відмінність від дії [init], яка відображає заздалегідь визначену форму. URL-адреса з параметром [?action=formulaire] насправді не має URL-адреси. Тому вона буде такою самою, як та, що дозволила відобразити сторінку підтвердження. Якщо згадати попереднє дослідження, це URL-адреса каталогу додатка. Отже, запит пройде через контролер. Тепер він повинен обробити дію [formulaire]. Код [global.asax.vb] змінюється наступним чином:
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
' отримуємо дію, яку потрібно виконати
Dim action As String
If Request.QueryString("action") Is Nothing Then
action = "init"
Else
action = Request.QueryString("action").ToString.ToLower
End If
' виконується дія
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
У випадку, якщо дія є «формою», достатньо просто передати запит на сторінку [formulaire.aspx]. Відомо, що ця сторінка відображає заздалегідь визначену форму, у якій немає жодних змінних частин. Отже, ця сторінка не може відобразити форму з тими значеннями, які вона мала на момент її підтвердження. Тут ми прагнемо підкреслити саме цей момент. Якщо всі файли додатка розміщено в <application-path>, ми запускаємо Cassini з параметрами (<application-path>,/mvcform2), а потім звертаємося за URL-адресою [http://localhost/mvcform2]. Ми отримуємо таку сторінку (частковий вигляд):

Ми заповнюємо форму наступним чином, а потім підтверджуємо її:

Ми отримуємо таку сторінку підтвердження:

Ми використовуємо посилання [Retour au formulaire], яке є (але не відображається) на сторінці вище. Ми отримуємо таку відповідь від сервера:

Ми бачимо, що:
- запитана URL-адреса дійсно містить параметр action=formulaire, як і було потрібно
- відображена форма втратила введені значення.
Ми знаємо, чому не бачимо введених значень. Якщо подивитися на код документа [formulaire.aspx], то можна побачити, що все є статичним, і тому система змушена щоразу відображати одну й ту саму сторінку. Очевидно, що нам потрібно зробити цей код динамічним. Він повинен відображати значення, підтверджені користувачем. Але де їх зберігати?
Нагадаємо «залізне правило» безстатного протоколу HTTP:
- запитується URL-адреса [http://localhost/mvcform2] — отримується відповідь. Зв’язок TCP-IP між клієнтом і сервером відкривається на початку запиту і закривається після отримання відповіді.
- користувач вводить, а потім підтверджує дані. Запитується URL-адреса [http://localhost/mvcform2/?action=validation] — отримується відповідь. Між двома партнерами було відкрито, а потім закрито нове з’єднання TCP-IP.
- Користувач використовує посилання [Retour au formulaire]. Запитується URL-адреса [http://localhost/mvcform2/?action=formulaire] — отримується відповідь. Між двома партнерами знову було відкрито, а потім закрито нове з’єднання TCP-IP.
Цикли «запит-відповідь» є незалежними один від одного, оскільки кожен із них використовує нове з’єднання TCP-IP. Коли клієнтсько-серверний додаток використовує єдине з’єднання TCP-IP для серії обмінів, сервер може ідентифікувати клієнта за його з’єднанням. Таким чином, він може запам’ятати інформацію, яку пов’яже з конкретним з’єднанням, і таким чином відстежувати обміни. Коли обміни відбуваються через різні з’єднання, сервер не може ідентифікувати клієнта за з’єднанням. Потрібен інший спосіб. Один із них ми розглянули в попередньому розділі: механізм сеансу. Він дозволяє циклам «запит-відповідь» зберігати інформацію в об’єкті [Session], доступному для всіх наступних циклів.
Тепер, коли ми маємо додаток MVC із сесією, ми більше не можемо використовувати файл [global.asax] як контролер, як це було показано в попередньому розділі. Роль контролера додатка має виконувати спеціальна сторінка, призначена саме для цього. У даному випадку це буде сторінка [main.aspx]. Ми будемо діяти таким чином:
- коли користувач підтвердить свої дані (action=validation), контролер [main.aspx.vb] збереже їх у поточній сесії, перш ніж відобразити сторінку підтвердження.
- коли потрібно буде відобразити форму з введеними значеннями (action=formulaire), контролер [main.aspx.vb] отримає їх із сесії та помістить у контекст перед тим, як відобразити форму.
5.5.2. Новий контролер додатка
Контролер додатка складається з двох файлів [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
' отримуємо дію, яку потрібно виконати
Dim action As String
If Request.QueryString("action") Is Nothing Then
action = "init"
Else
action = Request.QueryString("action").ToString.ToLower
End If
' виконується дія
Select Case action
Case "init"
' відображається попередньо заповнена форма
Context.Items("formulaire") = initForm()
Server.Transfer("formulaire.aspx", True)
Case "validation"
' відображається сторінка підтвердження після збереження значень, відправлених у сесії
Session.Item("formulaire") = Request.Form
Server.Transfer("validation.aspx", True)
Case "formulaire"
' відображається форма зі значеннями, отриманими з сесії
Context.Items("formulaire") = Session.Item("formulaire")
Server.Transfer("formulaire.aspx", True)
Case Else
' відображається попередньо заповнена форма
Context.Items("formulaire") = initForm()
Server.Transfer("formulaire.aspx", True)
End Select
End Sub
Private Function initForm() As NameValueCollection
' ініціалізується форма
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
Тут ми бачимо суть структури контролера додатка, який ми розглядали раніше, з такими відмінностями:
- робота контролера здійснюється в процедурі [Form_Load]
- у разі дії [validation] значення форми, що містяться в [Request.Form], зберігаються в сесії, пов’язаній із ключем «форма». Потім виконання передається на сторінку [validation.aspx], яка відобразить ці значення.
- Для інших дій виконання в усіх випадках переходить на сторінку [formulaire.aspx]. Ця сторінка очікує у своєму контексті ключ «formulaire», який буде пов’язаний з об’єктом типу [Request.form] або c.a.d, або типу [NameValueCollection]. Цей об’єкт повинен містити набір значень полів форми.
- у разі, якщо дія має код [init] або є невизнаною, набір значень формується довільно за допомогою функції [initForm].
- у разі, якщо дія має код [formulaire], цим набором є набір [Request.Form], який був розміщений у сесії дією [validation]
5.5.3. Нова форма
Оскільки додаток більше не відображає той самий вміст у формі, її потрібно генерувати динамічно. Нова сторінка [formulaire.aspx] виглядає так:
<%@ 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>
Прокоментуємо динамічні змінні, що з’являються в коді HTML:
змінна | роль |
матиме значення «checked», якщо потрібно встановити прапорець [oui], і значення «» в іншому випадку | |
те саме стосується перемикача [non] | |
те саме стосується прапорця [C1] | |
те саме для прапорця [C2] | |
те саме стосується прапорця [C3] | |
текст, який потрібно ввести в поле [txtSaisie] | |
текст, який потрібно розмістити в полі [txtMdp] | |
текст, який потрібно розмістити в полі [areaSaisie] | |
текст HTML з опцій списку вибору [cmbValeurs] | |
текст HTML з опцій списку вибору [lstSimple] | |
текст HTML з опцій списку вибору [lstMultiple] | |
Значення цих змінних обчислюються контролером сторінки [formulaire.aspx.vb]:
Imports Microsoft.VisualBasic
Imports System.Collections.Specialized
Public Class formulaire
Inherits System.Web.UI.Page
' постійні поля форми
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"}
' динамічні поля форми
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
' отримуємо попередній запит із сесії
Dim form As NameValueCollection
If Not Context.Items("formulaire") Is Nothing Then
form = Context.Items("formulaire")
Else
form = New NameValueCollection
End If
' підготовка сторінки до відображення
' перемикачі
rdouichecked = ""
rdnonchecked = "checked"
If isEqual(form("rdMarie"), "oui") Then
rdouichecked = "checked"
rdnonchecked = ""
End If
' прапорці
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"
' поля введення
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
' списки
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
' повертає код HTML опцій тегу <select>
' значення: масив значень параметрів тегу
' назви: масив назв параметрів тегу
' вибори: параметри для вибору
Dim iValeur As Integer
Dim iSelection As Integer
Dim selected As String
Dim toString As String = ""
' проглядаємо список значень параметрів
For iValeur = 0 To valeurs.Length - 1
' перевіряється, чи слід вибрати поточне значення
selected = "" : iSelection = 0
Do While iSelection < sélections.Length And selected = ""
If valeurs(iValeur) = sélections(iSelection) Then selected = "selected"
iSelection += 1
Loop
' вставляється код HTML опції
toString += "<option " + selected + " value='" + valeurs(iValeur) + "'> " _
+ libelles(iValeur) + "</option>" + ControlChars.CrLf
Next
' повертається результат
Return toString
End Function
Private Function isEqual(Byval champ As Object, ByVal valeur As String) As Boolean
' повертає «true», якщо поле дорівнює значенню
If champ Is Nothing OrElse champ.ToString <> valeur Then
Return false
Else
Return true
End If
end function
End Class
Коли сторінка [formulaire.aspx] починає виконуватися, вона знаходить у своєму контексті ключ «форма», пов'язаний із набором значень полів, які вона має відобразити.
' отримуємо попередній запит із сесії
Dim form As NameValueCollection
If Not Context.Items("formulaire") Is Nothing Then
form = Context.Items("formulaire")
Else
form = New NameValueCollection
End If
Можна задатися питанням, навіщо перевіряється наявність об’єкта [Context.Items("formulaire")]. Адже контролер у будь-якому разі присвоює цьому об’єкту значення. Однак ніщо не заважає клієнту безпосередньо запросити сторінку [formulaire.aspx], оминаючи контролер. У такому випадку наведений вище код працюватиме з порожньою колекцією значень, але «збою» не відбудеться.
Код обходить отриманий масив значень, щоб обчислити всі динамічні змінні сторінки HTML, яка з ним пов’язана. Хоча цей код і довгий, він не є особливо складним, і ми залишаємо читачеві можливість самостійно вникнути в нього, щоб не перевантажувати це пояснення. Проте ми зупинимося на тому, як генерується код HTML із трьох списків типу [select]. Цей код генерується наступною функцією:
Private Function getOptions(ByRef valeurs() As String, ByRef libelles() As String, ByRef sélections() As String) As String
' повертає код HTML з опцій тегу <select>
' значення: масив значень параметрів тегу
' назви: масив назв параметрів тегу
' вибори: параметри для вибору
Dim iValeur As Integer
Dim iSelection As Integer
Dim selected As String
Dim toString As String = ""
' проглядаємо список значень параметрів
For iValeur = 0 To valeurs.Length - 1
' перевіряється, чи слід вибрати поточне значення
selected = "" : iSelection = 0
Do While iSelection < sélections.Length And selected = ""
If valeurs(iValeur) = sélections(iSelection) Then selected = "selected"
iSelection += 1
Loop
' вставляється код HTML опції
toString += "<option " + selected + " value='" + valeurs(iValeur) + "'> " _
+ libelles(iValeur) + "</option>" + ControlChars.CrLf
Next
' повертаємо результат
Return toString
End Function
Нагадаємо, що параметри тегу <select> відповідають такому коду HTML:
Отже, для кожного параметра потрібно згенерувати три елементи інформації:
- значення параметра в атрибуті [value]
- текст опції між тегами <option> та </option>
- ключове слово [selected], якщо опцію потрібно вибрати зі списку
Щоб згенерувати ці три елементи для кожної з опцій, функція [getOptions] отримує три значення:
- масив значень опцій у [valeurs]
- масив текстів опцій у [libelles]
- масив значень для вибору в [sélections]
5.5.4. Сторінка підтвердження
Сторінка перевірки залишається без змін:
[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
'отримуємо надіслані параметри
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")
' зберігаємо їх у сесії
'Session("formulaire") = Request.Form
End Sub
Private Function getValue(ByVal champ As String) As String
' отримуємо значення поля [champ] із відправленого запиту
' щось таке?
If Request.Form(champ) Is Nothing Then Return ""
' отримуємо значення поля або полів
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. Тестування
Файли [main.aspx, main.aspx.vb,formulaire.aspx,formulaire.aspx.vb, validation.aspx, validation.aspx.vb] розміщуються в <application-path>, а Casini запускається з параметрами (<application-path>,/mvcform3). Потім ми звертаємося за URL-адресою [http://localhost/mvcform3/main.aspx]. Ми отримуємо попередньо ініціалізовану форму:

Заповнюємо форму наступним чином:

Натискаємо кнопку [Envoyer], розташовану вище. Отримуємо таку відповідь від сервера:

Ми використовуємо наведене вище посилання [Retour au formulaire], щоб повернутися до форми. Отримуємо таку нову відповідь:

Ми бачимо саме ту форму, яку підтвердили.
5.5.6. Висновок
Попередній приклад показав, що можна зберігати стан сторінки протягом циклів запит-відповідь між клієнтом і сервером. Проте це завдання не є простим. У наступному розділі ми побачимо, що за допомогою ASP.NET можна дозволити серверу самостійно відновлювати стан сторінки.



