ЛАБОРАТОРНАЯ РАБОТА 3

ИСПОЛЬЗОВАНИЕ ТЕХНОЛОГИИ AJAX

ПРИ ПРОГРАММИРОВАНИИ WEB-ПРИЛОЖЕНИЙ

1. Цель работы

Целью работы является изучение технологии AJAX при программировании Web-приложений.

2. Задачи

Задачами лабораторной работы являются овладение навыками создания связанных элементов управления на Web-странице приложения, использования объекта XmlHttpRequest, использования асинхронных запросов к серверу.

3. Теоретическая часть

Традиционное веб-программирование. Классическая модель веб-приложения действует следующим образом: большинство действий пользователя отправляют обратно на сервер HTTP-запрос. Сервер производит необходимую обработку – получает данные, обрабатывает числа, взаимодействует с различными унаследованными системами и затем выдает HTML страницу клиенту. Все это время пользователю не только приходится ожидать ответов от сервера, но и для каждой пары «запрос/ответ» страница перерисовывается заново.

Таким образом, веб-сервер отвечает на каждый запрос, возвращая совершенно новую страницу HTML с обновленными данными, а весь процесс повторяется снова и снова.

Кроме того, в традиционном веб-программировании все сведения, связанные со страницей, и элементы управления на странице теряются при каждом цикле обработки. Например, если пользователь ввел сведения в текстовое поле, то эти сведения будут потеряны в ходе цикла обработки от веб-обозревателя или клиентского устройства к серверу.

AJAX. Ajax – принципиально новый подход к веб-программированию. Расшифровывается AJAX как Asynchronous JavaScript and XML (Асинхронный JavaScript и XML).

НЕ нашли? Не то? Что вы ищете?

Веб-страница отправляет запросы с помощью функции JavaScript, обеспечивающей взаимодействие с сервером. Для веб-сервера ничего не изменилось – он по-прежнему отвечает на каждый запрос. Однако ответ сервера содержит только данные, необходимые для страницы без разметки и представления. Большая часть страницы остается неизменной, обновляются только части, которые должны быть изменены. JavaScript динамически обновляет веб-страницу без перерисовки.

Простыми словами можно сформулировать так: AJAX – это когда с помощью JavaScript можно запрашивать и получать данные с сервера, не перезагружая станицу сайта. Несмотря на то, что в названии технологии явным образом присутствует слово «XML», сервер может возвращать свой ответ не только в XML-формате, но и в более привычном текстовом виде.

Главное отличие в том, что web-страница, созданная с помощью AJAX, может взаимодействовать с web-сервером в «асинхронном» режиме, запрашивая и получая данные без необходимости обновления страницы в браузере. Обычная web-страница для обмена данными с сервером должна быть обновлена целиком. Например, отправка данных web-формы на сервер и отображение ответа происходят на разных web-страницах: первая содержит данные формы, а вторая генерируется сервером в ответ на запрос браузера. Такая технология требует от браузера дополнительного сетевого трафика и времени, затрачиваемого на отображение страницы. К тому же web-сервер даже при минимальных отличиях между двумя web-страницами часто вынужден передавать большие объемы информации при загрузке каждой из них.

AJAX же позволяет обновлять лишь те фрагменты web-страницы, которые действительно изменялись, не перезагружая страницу целиком. При этом браузер обменивается данными со сценарием на web-сервере, передавая минимальную информацию – только то, что нужно.

AJAX позволяет делать запросы к серверу асинхронными. Термин «асинхронность» означает, что во время обработки запроса пользователь может продолжить работу с приложением.

Объект XMLHTTPRequest. Объект XMLHttpRequest дает возможность браузеру делать HTTP-запросы к серверу без перезагрузки страницы.

В разных браузерах этот объект создается разными способами. Так, к примеру, в браузерах Safari, Firefox, Mozilla и большинстве альтернативных браузеров этот объект называется XMLHttpRequest, в Internet Explorer – это объект ActiveX «Msxml2.XMLHTTP», в других браузерах Microsoft – это объект ActiveX «Microsoft. XMLHTTP».

Отправка запросов с помощью объекта XMLHttpRequest выполняется с помощью трех основных методов:

– open(Method, Url, async) – инициализация подключения: Method – HTTP-метод (POST или GET); Url – URL сценария, работающего на веб-сервере (куда направляется этот запрос); async – вид подключения (true, если подключение асинхронное, false, если подключение синхронное).

– send(data) – параметры отправки запроса. Обычно в качестве параметра этому методу передается значение null, т. е. без данных;

– onreadystatechange – функция обратного вызова, т. е. название той JavaScript-функции, которая должна быть вызвана при получении ответа от сервера.

Данные, полученные в результате запроса к серверному сценарию, могут быть представлены как в форме текста (свойство ResponseText), так и в виде XML-разметки (свойство ResponseXml).

JavaScript. JavaScript может использоваться как для синхронных, так и для асинхронных запросов к серверу. Обработчики событий JavaScript позволяют организовать вызов кода JavaScript при выполнении различных условий. Типичные примеры – onClick() и onChange().

Ajax по существу помещает технологию JavaScript и объект XMLHttpRequest между Web-формой и сервером. Когда пользователи заполняют формы, данные передаются в какой-то JavaScript-код, а не прямо на сервер. JavaScript-код собирает данные формы и передает запрос на сервер. Пока это происходит, форма на экране пользователя не мелькает, не мигает, не исчезает и не блокируется (если запрос асинхронный). Другими словами, код JavaScript передает запрос в фоновом режиме. Пользователи могут продолжать вводить данные, прокручивать страницу и работать с приложением.

Затем сервер передает данные обратно в JavaScript-код (все еще находящийся в Web-форме), который решает, что делать с данными. К примеру, он может обновить поля формы "на лету", пользователи получают новые данные без подтверждения или обновления их форм. JavaScript-код может даже получить данные, выполнить какие-либо вычисления и передать еще один запрос.

Браузер. Именно браузер выполняет код JavaScript, незаметно для пользователя он производит такие важные операции, как сохранение значений переменных, создание новых типов и обработка сетевых запросов, которые могли быть выданы вашим кодом.

Браузер организует передачу запросов веб-серверу и разбирается, что делать с ответами, полученными от этих серверов. Но это вовсе не означает, что запросы серверу передает браузер, а не код. Он просто поддерживает такую передачу, организует низкоуровневые сетевые протоколы, обеспечивающие работу этого кода.

Состояние готовности запроса. Состояние готовности запроса определяет, на какой стадии находится его обработка: запрос инициализируется, установлена связь с сервером, сервер завершил обработку и т. д. Выделяются следующие значения состояний:

0 – подключение не инициализировано при загрузке веб-страницы создается новый объект запроса;

1 – подключение инициализировано – после инициализации подключения запрос отправляется серверу;

2 – в процессе обработки запроса – сервер передает запрос нужному сценарию или программе, и эта программа отвечает на запрос;

3 – получение ответа сервера – на этой стадии браузер делает доступным код состояния и заголовки запроса, полученные от сервера;

4 – ответ сервера готов – сервер завершил обработку: все данные доступны в свойстве responseText объекта запроса.

Статус запроса. Состояние готовности запроса указывает браузеру, на какой стадии находится обработка запроса: инициализация, обработка, завершение и т. д. Однако сам факт завершения еще не означает, что запрос завершился успешно. За это отвечает статус запроса. Статус указывает, что произошло во время запроса, и развивались ли события именно так, как предполагалось.

Работает статус следующим образом. Объект запроса XMLHttpRequest отправляет запрос веб-серверу вместе с URL сценария, который должен его обработать.

Сервер определяет, какой код статуса он должен вернуть. Если программа успешно обработала запрос, возвращается статус 200. Если сервер не может найти программу, указанную в URL, он возвращает код статуса 404. Статус возвращает код состояния и код статуса на основании того, удалось ли найти запрашиваемый ресурс, и какие данные были получены от этого ресурса. Завершив обработку запроса, сервер возвращает код статуса и состояние готовности 4.

Функция обратного вызова. Функция обратного вызова – это та функция, которая запускается браузером при изменении состояния запросов. Она запускается каждый раз, когда с запросом что-то происходит, а не только при получении ответа. Иначе говоря, функция обратного вызова вызывается несколько раз: при переходе состояния готовности с 1 на 2, при следующем переходе с 2 на 3, и в последний раз при переходе с 3 на 4.

Однако сервер гарантирует наличие данных, пригодных для использования, только в состоянии готовности 4. А это означает, что текущее состояние готовности должно проверяться перед обновлением соответствующей части веб-страницы, потому что в противном случае страница может содержать неполные или недействительные данные.

Если проверка показывает, что обработка запроса завершена, необходимо убедиться в отсутствии ошибок; эта информация хранится в коде статуса. Чтобы быть уверенным в том, что запрос был обработан, а страницу можно обновлять данными, полученными от сервера, необходимо как состояние готовности, так и статус.

Значит, состояние готовности должно быть равно 4 (что означает, что запрос был полностью обработан), а статус должен быть равен 200 (который указывает на отсутствие ошибок).

Модель DOM. Для представления кода HTML, образующего веб-страницу, браузер использует модель дерева объектов Document Object Model (DOM). DOM работает с Ajax, но DOM не является частью Ajax.

Для просмотра и модификации модели DOM используется код JavaScript. Изменения, вносимые в DOM, автоматически воспроизводятся на веб-странице, отображаемой браузером. При внесении любых изменений в модель веб-страницы браузер автоматически обновляет отображаемую страницу.

AJAX в PHP и JSP. В веб-приложениях PHP и JSP технология AJAX используется одинаково. Создается JavaScript-сценарий (в самом веб-приложении или в отдельном файле), в нем программируется создание экземпляров объекта XmlHttpRequest и функции обратного вызова, которые выполняются при получении ответа на запрос от сервера.

AJAX в ASP.NET. Приложения реализуют AJAX-функциональность как с помощью традиционных объектов XmlHttpRequest, так и более «продвинутым» способом ­ с помощью элементов управления, предоставляемых надстройкой Ajax Control Toolkit. В лабораторной работе рассматриваются оба этих способа.

Использование объектов XmlHttpRequest в приложениях выполняется точно так же, как и в PHP- и JSP-приложениях – с помощью соответствующих JavaScript-сценариев.

Надстройка Ajax Control Toolkit содержит более 40 элементов управления, таких как CollapsiblePanel, ColorPicker, MaskedEdit, Calendar, Cascading Dropdown и др. С помощью Ajax Control Toolkit можно построить веб-формы с использованием AJAX (Ajax-enabled Web Forms). Достаточно просто перетащить элементы управления с панели инструментов Visual Studio Toolbox на страницу Web-форму.

4. Порядок выполнения работы

Предварительные замечания

В лабораторной работе нужно связать три раскрывающихся списка (факультетов, специальностей и групп), расположенных на странице Index. php. При выборе значения из списка факультетов в списках специальностей и групп должны остаться только те значения, которые соответствуют выбранному факультету. При выборе значения специальности из списка специальностей должен быть отфильтрован список групп – остаются только те группы, которые относятся к выбранной специальности.

Технология ASP.NET и СУБД Microsoft SQL Server

А1. Объекты XMLHttpRequest

1. Создать новый Web-сайт:

Пуск | Microsoft Visual Studio 2005 | Microsoft Visual Studio 2005

ф. Microsoft Visual Studio | File → New → Web Site… → ф. New Web Site → Visual Studio Installed Templates → выбр. Web Site →

Location → выбр. HTTP → http://имя_сервера(например, localhost)/Lab1_ASP

Language → выбр. Visual C#

2. Перейти на страницу ввода программного кода:

ф. Lab1_ASP → Default. aspx → Source | удалить весь код, расположенный между открывающим и закрывающим тегами элемента BODY

3. Задать заголовок страницы Default. aspx. Для этого между открывающим и закрывающим тегами элемента HEAD ввести следующий код:

<TITLE>Успеваемость студентов</TITLE>

4. Подключить библиотеки для работы с базами данных (System. Data, System. Data. SqlTypes, System. Data. SqlClient). Для этого после строки программного кода

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default. aspx. cs" Inherits="_Default"%>

добавить следующие строки:

<%@Import Namespace="System. Data"%>

<%@Import Namespace="System. Data. SqlTypes"%>

<%@Import Namespace="System. Data. SqlClient"%>

5. Создать серверную функцию Page_Load, выполняемую при загрузке страницы:

void Page_Load(object sender, EventArgs e)

{

5.1 Проверить, загружается ли форма в первый раз или она должна формироваться как результат обработки данных, введенных пользователем:

if (!Page. IsPostBack)

{

5.2 Если форма загружается в первый раз, задать элементу faculty (раскрывающийся список факультетов) обработчик события onchange (изменение выбранного значения) – функцию startRequest:

this. faculty. Attributes. Add("onchange", "return startRequest();");

5.3 Вызвать функцию ListFaculty, формирующую список факультетов, полученный из базы данных:

ListFaculty();

5.4 Проверить, присвоено ли значение переменной facultyID. Если это условие выполняется, то вызвать функцию GetSpecByFacultyID (формирование списка специальностей факультета) и передать ей в качестве параметра значение facultyID:

if (facultyID!= "")

{

GetSpecByFacultyID(facultyID);

}

5.5 Проверить, присвоено ли значение переменной specID. Если значение присвоено, то вызвать функцию GetGrBySpecID (формирование списка групп специальности) и передать ей в качестве параметра значение specID:

if (specID!= "")

{

GetGrBySpecID(specID);

}

}

}

6. Создать строковую переменную facultyID:

private string facultyID

{

6.1 Объявить метод GET получения значения переменной:

get

{

6.2 Проверить, был ли передан странице параметр facultyID и содержит ли он какое-нибудь значение:

if (Request["facultyID"] != null && Request["facultyID"].ToString() != "")

6.3 Если значение facultyID передано, то вернуть его:

{

return Request["facultyID"];

}

6.4 В противном случае вернуть пустую строку:

else

{

return "";

}

}

}

7. Аналогичным образом создать строковую переменную specID:

private string specID

{

get

{

if (Request["specID"] != null && Request["specID"].ToString() != "")

{

return Request["specID"];

}

else

{

return "";

}

}

}

8. Создать функцию GetSpecByFacultyID с входным строковым параметром facultyID – формирование списка специальностей (элемента select).

8.1 Ввести имя функции и объявить входной параметр :

private void GetSpecByFacultyID(string facultyID)

{

8.2 Создать строковую переменную connStr и записать в нее параметры соединения с базой данных:

string connStr = "Data Source=имя_компьютера;Initial Catalog=University;Integrated Security=True";

8.3 Соединиться с базой данных University:

SqlConnection conn = new SqlConnection(connStr);

8.4 Создать строковую переменную sql и записать в нее текст SQL-запроса формирования списка специальностей, соответствующих факультету, код которого размещается в переменной facultyID:

string sql = "select '0' as id, 'Выбор специальности...' as name from Speciality union select id, name from Speciality where faculty='" + facultyID + "'";

8.5 Выполнить запрос и занести результат в экземпляр объекта SqlDataReader:

SqlCommand cmd = new SqlCommand(sql, conn);

conn. Open();

SqlDataReader dr = cmd. ExecuteReader();

8.6 Создать строковую переменную s и записать в нее разметку открывающего тега элемента SELECT. Указать, что элемент является серверным, и задать стиль его представления. Задать выражение, присваивающее выбранное значение списка элементу с ID="spec":

string s = "<select runat='server' style='width: 350px' onChange=\"javascript:document. getElementById('spec').value=this. value;return startRequest2();\">";

8.7 Задать цикл по результату запроса:

while (dr. Read())

{

8.8 Сформировать элементы списка SELECT. В качестве значения для каждого элемента списка указать значение поля id, в качестве отображаемого текста – значение поля name:

s += "<option value='" + dr["id"] + "'>" + dr["name"] + "</option>";

}

8.9 Добавить к содержимому переменной s разметку закрывающего тега элемента SELECT:

s += "</select>";

8.10 Закрыть экземпляр объекта SqlDataReader и соединение с базой данных:

dr. Close();

conn. Close();

8.11 Вывести в поток значение переменной s:

this. Response. Write(s);

this. Response. End();

}

9. Аналогичным образом создать функцию GetGrBySpecID с входным параметром specID – формирование списка групп заданной специальности.

10. Создать функцию ListFaculty – формирование списка факультетов и заполнение раскрывающегося списка с идентификатором faculty

10.1 Задать имя функции:

private void ListFaculty()

{

10.2 В строковую переменную sql занести код запроса, извлекающего список факультетов из базы данных:

string sql = "select '0' as id, 'Выбор факультета...' as name from Faculty union select * from Faculty";

10.3 Установить соединение с базой данных и выполнить запрос к ней:

string constring = "Data Source=имя_компьютера;Initial Catalog=University;Integrated Security=True";

SqlDataAdapter sda = new SqlDataAdapter(sql, constring);

10.4 Создать экземпляр объекта DataSet и заполнить его результатом запроса:

DataSet ds = new DataSet();

sda. Fill(ds);

10.5 Заполнить список faculty значениями объекта DataSet:

faculty. DataSource = ds;

faculty. DataTextField = "name";

faculty. DataValueField = "id";

faculty. DataBind();

}

11. Скопировать содержимое файла Index. aspx из лабораторной работы 1, начиная с открывающего тега элемента html и заканчивая соответствующим закрывающим тегом.

12. Заменить идентификатор элемента spec на любое другое значение, к примеру, DropDownList1. Поместить полученный элемент между открывающим и закрывающим тегами элемента DIV с ID=" gridiv "

<div id="gridiv">…</div>

13. Заменить идентификатор элемента gr на другое значение, например, groups. Поместить полученный элемент между открывающим и закрывающим тегами элемента DIV с ID=" div_gr "

<div id="div_gr">…</div>

13. Создать два скрытых элемента spec и groups:

<asp:HiddenField ID="spec" runat="server"/>

<asp:HiddenField ID="gr" runat="server"/>

14. Создать клиентский сценарий JavaScript, создающий и использующий объект XMLHttpRequest

14.1 Ввести открывающий тег сценария:

<script type="text/javascript">

14.2 Создать переменную xmlHttp для хранения экземпляра объекта XMLHttpRequest:

var xmlHttp;

14.3 Создать функцию createXMLHttpRequest, формирующую экземпляр объекта XMLHttpRequest для различных типов браузеров:

function createXMLHttpRequest()

{

if (window. ActiveXObject)

{

xmlHttp = new ActiveXObject("Microsoft. XMLHTTP");

}

else if (window. XMLHttpRequest)

{

xmlHttp = new XMLHttpRequest();

}

}

14.4 Создать функцию startRequest формирования запроса на основе объекта XMLHttpRequest.

function startRequest()

{

14.4.1 Создать переменную facultyID и присвоить ей значение, выбранное в раскрывающемся списке faculty:

var facultyID=document. getElementById('faculty').value;

14.4.2 Создать экземпляр объекта XMLHttpRequest:

createXMLHttpRequest();

14.4.3 Задать функцию обратного вызова handleStateChange:

xmlHttp. onreadystatechange = handleStateChange;

14.4.4 Определить параметры запроса информации о специальностях по коду факультета (facultyID):

xmlHttp. open("GET", "?facultyID="+facultyID, true);

xmlHttp. setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");

xmlHttp. send(null);

}

14.5 Создать функцию обратного вызова handleStateChange:

function handleStateChange()

{

14.5.1 Проверить состояние готовности запроса («4» – запрос выполнен)

if(xmlHttp. readyState == 4)

{

14.5.2 Проверить статус запроса («200» – запрос выполнен успешно)

if(xmlHttp. status = = 200)

{

14.5.3 Заменить содержимое DIV-элемента gridiv на HTML-код, полученный в результате выполнения запроса:

document. getElementById("gridiv").innerHTML=xmlHttp. responseText;

}

}

}

14.6 Аналогичным образом (см. пп. 14.4–14.5) настроить запрос XmlHTTPRequest на получение информации о группах по значению кода специальности:

function startRequest2()

{

var facultyID=document. getElementById('spec').value;

createXMLHttpRequest();

xmlHttp. onreadystatechange = handleStateChange2;

xmlHttp. open("GET", "?specID="+facultyID, true);

xmlHttp. setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");

xmlHttp. send(null);

}

function handleStateChange2()

{

if(xmlHttp. readyState == 4)

{

if(xmlHttp. status == 200)

{

document. getElementById("div_gr").innerHTML=xmlHttp. responseText;

}

}

}

14.7 Ввести закрывающий тег сценария:

</script>

15. Проверить работоспособность созданного Web-приложения. Для этого перейти на страницу Lab3_ASP - Microsoft Visual Studio | Default. aspx и нажать сочетание клавиш [Ctrl+F5].

А2. Библиотека AJAX Toolkit

1. Создать новый Web-сайт:

Пуск | Microsoft Visual Studio 2005 | Microsoft Visual Studio 2005

ф. Microsoft Visual Studio | File → New → Web Site… → ф. New Web Site → Visual Studio Installed Templates → выбр. AJAX-Enabled Web Site→

Location → выбр. HTTP → http://имя_сервера(например, localhost)/Lab3_ASP

Language → выбр. Visual C#

На странице Default. aspx должна появиться следующая строка:

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

Если строка не появилась, то добавить ее вручную.

2. Добавить библиотеку компонентов AJAX Toolkit

Ф. Toolbox | пр. кн. мыши | выбр. Add Tab | ввести текст «AJAX Control Toolkit»

Вкл. AJAX Control Toolkit | пр. кн. мыши → Choose Items...

Ф. Choose toolbox items… | кн. Browse → выбр. файл AjaxControlToolkit. dll → кн. OK

3. Перейти на страницу ввода программного кода:

ф. Lab3_ASP → Default. aspx → Source | удалить весь код, расположенный между открывающим и закрывающим тегами элемента BODY

4. Скопировать весь код, размещенный между открывающим и закрывающим тегами BODY (включая сами эти теги), из файла Index. aspx первой лабораторной работы.

5. Ввести элемент ScriptManager:

<asp:ScriptManager ID="ScriptManager1" runat="server" />

6. Создать Web-сервис, содержащий методы извлечения из базы данных информации о факультетах, специальностях, группах и успеваемости студентов.

6.1 Создать Web-сервис University. asmx

Ф. Solution Explorer | пр. кн. мыши Add New Item…

Ф. Add New Item → выбр. Web Service →

Name → University. asmx | выбр. Place code in separate file

Language → выбр. Visual C# | кн. OK

6.2 Для работы с базами данных, массивами и списками значений, AJAX-компонентами подключить следующие библиотеки классов:

using System. Collections. Generic;

using System. Data;

using System. Data. SqlClient;

using AjaxControlToolkit;

6.2 Создать Web-метод GetSpecsByFacultyId получения данных о специальностях по коду факультета (входной параметр метода – код факультета (переменная faculties)). Переменная faculties содержит значения идентификаторов факультетов из элемента CascadingDropDown, разделенные символом « ; »:

[System. Web. Services. WebMethod]

[System. Web. Script. Services. ScriptMethod]

public CascadingDropDownNameValue[] GetSpecsByFacultyId(string faculties)

{

6.3 Создать строковый массив _ faculties, получаемый из выделения подстрок методом Split, которому в качестве символов-разделителей передаются « : » и « ; »:

string[] _ faculties = faculties. Split(':', ';');

6.4 Определить выбранное в раскрывающемся списке факультетов значение facultyID. Оно второе в массиве _ faculties:

string facultyID = _ faculties [1];

6.5 Создать список значений _specs для хранения данных о специальностях, полученных в результате выполнения запроса:

List<CascadingDropDownNameValue> _specs = new List<CascadingDropDownNameValue>();

6.6 Создать строковую переменную sql и записать в нее SQL-код запроса на получение данных о специальностях по коду факультета:

string sql = "select '0' as id, 'Выбор специальности...' as name from Speciality union select id, name from Speciality where faculty='" + facultyID + "'"; ;

6.7 Создать строковую переменную constring и записать в нее параметры соединения с базой данных University:

string constring = "Data Source=имя_сервера;Initial Catalog=University;Integrated Security=True";

6.8 Создать экземпляр класса SqlDataAdapter и в качестве параметров передать ему запрос на получение данных и параметры соединения:

SqlDataAdapter sda = new SqlDataAdapter(sql, constring);

6.9 Записать результат запроса в экземпляр класса DataTable:

DataTable dt = new DataTable();

sda. Fill(dt);

6.10 В цикле по записям результата запроса заполнить соответствующий список специальностей класса CascadingDropDownList:

foreach (DataRow _r in dt. Rows)

{

_specs. Add(new CascadingDropDownNameValue(_r["name"].ToString(), _r["id"].ToString()));

}

6.11 Вернуть полученный список специальностей:

return _specs. ToArray();

}

6.12 Аналогичным образом создать Web-метод GetGrsBySpecID, формирующий список групп по идентификатору специальности.

7. Вернуться к файлу Index. aspx.

8. Определить заполнение списка факультетов информацией из базы данных при загрузке страницы.

8.1 Задать область ввода сценария на С#:

<script language="C#" runat="server">

</script>

8.2 Создать обработчик события загрузки страницы. Для этого между открывающим и закрывающим тегами script ввести следующий код:

void Page_Load(object sender, EventArgs e)

{

}

8.3 Создать строковую переменную sql и записать в нее текст запроса к базе данных на извлечение информации о факультетах. Для этого между открывающей и закрывающей фигурными скобками (п. 8.2) ввести следующий код:

string sql = "select '0' as id, 'Выбор факультета...' as name from Faculty union select * from Faculty";

8.4 Создать строковую переменную constring и записать в нее параметры соединения с базой данных University

string constring = "Data Source=имя_сервера;Initial Catalog=University;Integrated Security=True";

8.5 Создать адаптер данных (экземпляр класса SqlDataAdapter) для выполнения запроса к базе данных:

SqlDataAdapter sda = new SqlDataAdapter(sql, constring);

8.6 Определить экземпляр класса DataSet и заполнить его данными из объекта SqlDataAdapter:

DataSet ds = new DataSet();

sda. Fill(ds);

8.7 Заполнить раскрывающийся список факультетов (элемент управления с ID="faculty") данными из объекта DataSet:

faculty. DataSource = ds;

faculty. DataTextField = "name";

faculty. DataValueField = "id";

faculty. DataBind();

9. Задать элемент CascadingDropDown, формирующий список специальностей в зависимости от выбранного значения факультета. Для этого в любой позиции между открывающим и закрывающим тегами BODY ввести следующий код:

<ajaxToolkit:CascadingDropDown ID=" updateSpec" runat="server"

Category="Specs" LoadingText="Список загружается..." ParentControlID="faculty"

TargetControlID="spec" ServicePath="University. asmx"

ServiceMethod="GetSpecsByFacultyId" />

Здесь ID="updateSpec" – идентификатор элемента управления; runat="server" – указание на то, что элемент является серверным; Category="Specs" – категория значений; LoadingText="Список загружается..." – текст, который будет видеть пользователь, пока выполняется запрос и происходит загрузка списка; ParentControlID="faculty" – «родительский» элемент, т. е. такой раскрывающийся список, на основании которого выполняется запрос к серверу; TargetControlID="spec" – «дочерний» (зависимый) элемент, т. е. тот раскрывающийся список, значения которого формируются на основании значения, выбранного в родительском элементе; ServicePath="University. asmx" – используемый Web-сервис (здесь указывается относительный путь, потому что Web-сервис был определен в той же папке, что и приложение); ServiceMethod="GetSpecsByFacultyId" – метод Web-сервиса, который используется для заполнения дочернего раскрывающегося списка.

10. Аналогичным образом создать элемент CascadingDropDown, формирующий список групп в зависимости от выбранного значения специальности через метод GetGrsBySpecID Web-сервиса University. asmx.

11. Скопировать в папку с приложением файл Browse. aspx.

12. Проверить работоспособность созданного Web-приложения. Для этого перейти на страницу Lab3_ASP - Microsoft Visual Studio | Default. aspx и нажать сочетание клавиш [Ctrl+F5].

Технология PHP и СУБД MySQL

1. Создать папку, в которой будут размещены все файлы Web-приложения, и назвать ее, к примеру, Lab3_PHP.

2. Скопировать файлы Index. php и Browse. php из первой лабораторной работы в папку Lab3_PHP.

3. В текстовом редакторе (например, в «Блокноте») создать новый файл и сохранить его под именем GetSpecGr. php.

4. Ввести открывающий тег PHP-сценария

<?php

5. Установить соединение с базой данных MySQL University

5.1 Задать объект link соединения с базой данных

$link = @mysql_connect("localhost", "root") or die("Невозможно соединиться с сервером");

5.2 Выбрать базу данных University

$db=@mysql_select_db("university") or die("Нет такой базы данных");

5.3 Установить кириллическую кодировку (cp-1251) для корректной передачи и получения данных из базы данных. Для этого в сценарий PHP из предыдущего пункта ввести следующий код:

@mysql_query("SET SESSION character_set_results = cp1251;");

@mysql_query("SET SESSION Character_set_client = cp1251;");

@mysql_query("SET SESSION Character_set_results = cp1251;");

@mysql_query("SET SESSION Collation_connection = cp1251_general_ci;");

@mysql_query("SET SESSION Character_set_connection = cp1251;");

6. Создать переменную faculty и записать в нее значения параметра faculty, переданного со страницы Index. php:

$faculty = $_GET['faculty'];

7. Создать переменную sp_query для хранения текста запроса к базе данных, для извлечения информации о специальностях факультета, заданного переменной faculty группы:

$sp_query="select * from `speciality` where `faculty`=' ".$faculty." ' ";

8. Выполнить запрос к базе данных:

$sp=mysql_query($sp_query);

9. Создать переменную specOptions для хранения HTML-разметки элементов options элемента select с идентификатором spec (раскрывающийся список специальностей). Ввести первый элемент списка со значением 0 и отображаемым текстом «Выберите специальность»

$specOptions = '<option value="0">Выберите специальность</option>';

10. В цикле сформировать оставшиеся элементы списка на основании запроса sp. В качестве значения элемента списка использовать код специальности (поле ID), а отображаемый в списке текст – название специальности (поле name).

while ( $spec = mysql_fetch_array( $sp ) )

{

$specOptions = $specOptions.'<option value="'.$spec['ID'].'">'.$spec['name'].'</option>';

}

11. Аналогичным образом создать запрос на извлечение данных о группах заданного факультета (текст запроса: «$gr_query="SELECT groups. ID, groups. number, groups. spec FROM `faculty` , `speciality` , `groups` WHERE speciality. faculty = faculty. ID AND groups. spec = speciality. ID AND faculty. ID = ' ".$faculty." ' ";»)

12. Создать переменную grOptions для хранения HTML-разметки элементов options элемента select с идентификатором gr (раскрывающийся список групп). Сформировать элементы списка (по аналогии с пп. 9–10) в формате: значение – код группы (поле ID), отображаемый текст – специальность (поле spec)-номер группы (поле number).

13. Создать переменную response для представления полученных переменных specOptions и grOptions в формате XML с корневым элементом response и элементами options для хранения значений переменных specOptions и grOptions:

$response = '<?xml version="1.0" encoding="windows-1251" standalone="yes"?>'.

'<response>'.

'<options>'.

$specOptions.

'</options>'.

'<options>'.

$grOptions.

'</options>'.

'</response>';

14. Установить XML-формат передаваемых сценарием данных:

header('Content-Type: text/xml');

15. Вывести значение переменной $response;

echo $response;

16. Ввести закрывающий тег PHP-сценария

?>

17. В текстовом редакторе (например, в «Блокноте») создать новый файл и сохранить его под именем GetGr. php.

18. Открыть тег PHP-сценария (см. п. 4).

19. Установить соединение с базой данных University (см. п. 5).

20. Создать переменную spec и записать в нее значения параметра spec, переданного со страницы Index. php:

$spec = $_GET['spec'];

21. Создать запрос на извлечение данных о группах заданной специальности (текст запроса: «$gr_query="SELECT groups. ID, groups. number, groups. spec FROM `speciality` , `groups` WHERE groups. spec = speciality. ID AND speciality. ID = '".$spec." ' ";») (см. пп. 7–8).

22. Создать переменную grOptions для хранения HTML-разметки элементов options элемента select с идентификатором gr (раскрывающийся список групп). Сформировать элементы списка (по аналогии с пп. 9–10) в формате: значение – код группы (поле ID), отображаемый текст – специальность (поле spec)-номер группы (поле number) (см. пп. 9–10).

23. Создать переменную response для представления полученных переменной grOptions в формате XML с корневым элементом response и элементом options для хранения значения переменной grOptions (см. п. 13).

24. Установить XML-формат передаваемых сценарием данных:

header('Content-Type: text/xml');

25. Вывести значение переменной response;

echo $response;

26. Ввести закрывающий тег PHP-сценария

?>

27. В текстовом редакторе (например, в «Блокноте») создать новый файл и сохранить его под именем Ajax. js.

28. Создать переменную request для хранения экземпляра объекта XmlHttpRequest и присвоить ей значение null:

var request = null;

29. Создать функцию для инициализации экземпляра объекта XmlHttpRequest

29.1. Ввести имя функции (createRequest) и открывающую фигурную скобку:

function createRequest() {

29.2 Ввести программный код для попытки создания объекта XmlHttpRequest

try

{

request = new XMLHttpRequest();

}

29.3 Ввести программный код для попытки создания объекта XmlHttpRequest в браузерах Microsoft (например, в Internet Explorer):

catch (trymicrosoft) {

{

try {

request = new ActiveXObject("Msxml2.XMLHTTP");

}

29.4 Ввести программный код для попытки создания объекта XmlHttpRequest в браузерах, отличных от Microsoft:

catch (othermicrosoft) {

try {

request = new ActiveXObject("Microsoft. XMLHTTP");

}

29.5 В случае невозможности создания объекта XmlHttpRequest присвоить переменной request значение null:

catch (failed) {

request = null;

}

}

}

29.6 Если значение переменной request равно null, то вывести сообщение о невозможности создания объекта XmlHttpRequest

if (request == null) alert("Ошибка при создании объекта XMLHttpRequest!");

29.6 Ввести закрывающую фигурную скобку функции

}

30. Создать функцию selectedFac, которая должна запускаться при выбора значения из списка факультетов.

30.1 Ввести имя функции (selectedFac) и открывающую фигурную скобку:

function selectedFac() {

30.2 Извлечь значение выбранного из списка факультета и поместить это значение в переменную fac:

var fac = document. getElementById("faculty").value;

30.3 Создать переменную для формирования URL-адреса серверного PHP-сценария (getSpecGr. php), к которому будет обращаться объект XMLHttpRequest. Сформировать GET-запрос для передачи сценарию параметра faculty со значением переменной fac:

url = "getSpecGr. php? faculty=" + fac;

30.3 C помощью функции createRequest() создать объект XmlHttpRequest:

createRequest();

30.4 Инициализировать асинхронное подключение методом GET:

request. open("GET", url, true);

30.5 Задать функцию обратного вызова (makeListSpecGr). Для этого с помощью свойства onreadystatechange указать браузеру, что при изменении состояния готовности запроса, браузер должен вызывать функцию JavaScript, назначенную в объекте запроса:

request. onreadystatechange = makeListSpecGr;

30.6 Указать, что запрос не содержит данных (параметр запроса передается через URL):

request. send(null);

30.7 Ввести закрывающую фигурную скобку функции

}

31. Создать функцию makeListSpecGr

31.1 Ввести имя функции (makeListSpecGr) и открывающую фигурную скобку:

function makeListSpecGr()

{

31.2 Создать переменную spec и занести в нее объект с идентификатором spec (раскрывающийся список специальностей):

var spec = document. getElementById("spec");

31.3 Создать переменную gr и занести в нее объект с идентификатором gr (раскрывающийся список групп):

var gr = document. getElementById("gr");

31.4 Проверить состояние готовности запроса. Все операции должны выполняться только в том случае, если сервер завершил обработку запроса и все данные доступны в свойствах responseText или responseXML объекта запроса:

if (request. readyState == 4)

{

31.5 Проверить статус запрос. Все операции должны выполняться только в том случае, если программа успешно обработала запрос:

if (request. status == 200)

{

31.6 Создать переменную responseXML и занести в нее XML-результат работы серверного сценария:

responseXml = request. responseXML;

31.7 Создать переменную xmlDoc и занести в нее корневой элемент XML-результата (элемент response), полученного от сервера:

xmlDoc = responseXml. documentElement;

31.8 Создать переменную options_spec и занести в нее первый дочерний элемент корня XML-результата с именем options:

options_spec = xmlDoc. getElementsByTagName("options")[0];

31.9 Удалить все элементы раскрывающегося списка специальностей:

while(spec. options. length)

{

spec. remove(0);

}

31.10 Аналогичным образом удалить все элементы раскрывающегося списка групп.

31.11 Заполнить раскрывающийся список специальностей

31.11.1 Построить цикл по XML-элементам option элемента options со списком специальностей. Для этого ввести инструкцию for и открывающую фигурную скобку цикла:

for(var i=0; i<options_spec. getElementsByTagName("option").length; i++)

{

31.11.2 Создать новый элемент option:

var option = document. createElement('option');

31.11.3 Создать переменную text с текстовым содержимым текущего на итерации цикла элемента option:

var text = options_spec. getElementsByTagName("option")[i].text;

31.11.4 Создать переменную value и занести в нее значение атрибута value текущего на итерации цикла элемента option:

var value = options_spec. getElementsByTagName("option")[i].getAttribute("value") ;

31.11.5 Добавить в созданный в п. 31.11.2 элемент option атрибут value со значением из переменной value:

option. setAttribute('value',value);

31.11.6 Добавить в созданный в п. 31.11.2 элемент option текстовый узел со значением из переменной text:

option. appendChild(document. createTextNode(text));

31.11.7 Добавить созданный в п. 31.11.2 элемент option к элементу spec (списку специальностей):

spec. appendChild(option);

31.12 Аналогичным образом (см. п. 31.8) сформировать переменную options_gr для представления второго элемента options из XML-ответа сервера.

31.13. Заполнить раскрывающийся список групп (см. п. 31.11)

31.14 Ввести закрывающую угловую скобку проверки статуса запроса:

}

31.15 Ввести инструкцию «иначе», выполняющуюся в том случае, когда запрос к серверу был выполнен неудачно:

else

{

alert("Не удалось получить данные от сервера");

}

31.16 Ввести закрывающую угловую скобку проверки состояния готовности запроса:

}

31.17 Ввести закрывающую фигурную скобку функции

}

32. Создать функцию selSpec, которая должна запускаться при выбора значения из списка факультетов. (см. п. 30). Использовать следующий URL: url = "getListGr. php? spec=" + trim(spec);. В качестве функции обратного вызова использовать JavaScript-функцию makeListGr.

33. Создать функцию makeListGr (см. п. 31), формирующую список групп из XML-ответа серверного сценария getListGr. php.

34. Открыть файл Index. php в текстовом редакторе (например, Блокноте или Notepad2) или HTML-редакторе.

35. Ввести в Index. php ссылку на JavaScript-сценарий Ajax. js. Для этого между открывающим и закрывающим тегами элемента HEAD ввести следующий код:

<script type="text/javascript" src="Ajax. js"></script>

36. Добавить в раскрывающийся список факультетов (элемент select с именем faculty) вызов функции selectedFac при изменении выбранного значения списка. Для этого изменить открывающий тег элемента select следующим образом:

<select name="faculty" style="width: 350px" onChange="selectedFac()">

37. Аналогичным образом задать вызов функции selSpec при выборе специальности из раскрывающегося списка специальностей (элемент select с именем spec).

38. Протестировать полученное Web-приложение (см. лабораторную работу 1).

Технология JSP и СУБД MySQL

1. Запустить визуальную среду Eclipse Europe

Пуск | Программы | Eclipse

2. Создать новый проект

File → New → Web → Dynamic Web Project

3. Присвоить проекту имя Lab3_JSP

name → Lab3_JSP

4. Настроить Web-сервер для нового Web-приложения

Вкладка Servers → кл. пр. кн. мыши | выбр. New → Server →

ф. New Server | выбр. Apache Tomcat Server → кн. Finish

5. Добавить в проект новую JSP-страницу

ф. Project Explorer | Lab1_JSP | кл. пр. кн. мыши → выбр. New → JSP |

ф. New JavaServer Page | File name ← Default | удалить весь код элемента HTML

6. Скопировать в полученный файл весь код из файла Index. jsp из первой лабораторной работы.

7. Скопировать таблицу стилей style. css из предыдущей лабораторной работы и поместить ее в папку images, размещенную в каталоге с веб-приложением.

8. В любом редакторе (например, в «Блокноте») или в самой среде Eclipse создать новый файл и сохранить его под именем Ajax. js.

9. Создать переменную request для хранения экземпляра объекта XmlHttpRequest и присвоить ей значение null:

var request = null;

10. Создать функцию для инициализации экземпляра объекта XmlHttpRequest

10.1. Ввести имя функции (createRequest) и открывающую фигурную скобку:

function createRequest() {

10.2 Ввести программный код для попытки создания объекта XmlHttpRequest

try

{

request = new XMLHttpRequest();

}

10.3 Ввести программный код для попытки создания объекта XmlHttpRequest в браузерах Microsoft (например, в Internet Explorer):

catch (trymicrosoft) {

{

try {

request = new ActiveXObject("Msxml2.XMLHTTP");

}

10.4 Ввести программный код для попытки создания объекта XmlHttpRequest в браузерах, отличных от Microsoft:

catch (othermicrosoft) {

try {

request = new ActiveXObject("Microsoft. XMLHTTP");

}

10.5 В случае невозможности создания объекта XmlHttpRequest присвоить переменной request значение null:

catch (failed) {

request = null;

}

}

}

10.6 Если значение переменной request равно null, то вывести сообщение о невозможности создания объекта XmlHttpRequest

if (request == null) alert("Ошибка при создании объекта XMLHttpRequest!");

10.7 Ввести закрывающую фигурную скобку функции

}

11. Создать функцию selectedFac, которая должна запускаться при выбора значения из списка факультетов.

11.1 Ввести имя функции (selectedFac) и открывающую фигурную скобку:

function selectedFac() {

11.2 Извлечь значение выбранного из списка факультета и поместить это значение в переменную fac:

var fac = document. getElementById("faculty").value;

11.3 Создать переменную для формирования URL-адреса серверного PHP-сценария (getSpecGr. php), к которому будет обращаться объект XMLHttpRequest. Сформировать GET-запрос для передачи сценарию параметра faculty со значением переменной fac:

url = "getSpecGr. jsp? faculty=" + fac;

11.3 C помощью функции createRequest() создать объект XmlHttpRequest:

createRequest();

11.4 Инициализировать синхронное подключение методом GET:

request. open("GET", url, true);

11.5 Задать функцию обратного вызова (makeListSpecGr). Для этого с помощью свойства onreadystatechange указать браузеру, что при изменении состояния готовности запроса, браузер должен вызывать функцию JavaScript, назначенную в объекте запроса:

request. onreadystatechange = makeListSpecGr;

11.6 Указать, что запрос не содержит данных (параметр запроса передается через URL):

request. send(null);

11.7 Ввести закрывающую фигурную скобку функции

}

12. Создать функцию makeListSpecGr

12.1 Ввести имя функции (makeListSpecGr) и открывающую фигурную скобку:

function makeListSpecGr()

{

12.2 Создать переменную spec и занести в нее объект с идентификатором spec (раскрывающийся список специальностей):

var spec = document. getElementById("spec");

12.3 Создать переменную gr и занести в нее объект с идентификатором gr (раскрывающийся список групп):

var gr = document. getElementById("gr");

12.4 Проверить состояние готовности запроса. Все операции должны выполняться только в том случае, если сервер завершил обработку запроса и все данные доступны в свойствах responseText или responseXML объекта запроса:

if (request. readyState == 4)

{

12.5 Проверить статус запрос. Все операции должны выполняться только в том случае, если программа успешно обработала запрос:

if (request. status == 200)

{

12.6 Создать переменную responseXML и занести в нее XML-результат работы серверного сценария:

responseXml = request. responseXML;

12.7 Создать переменную xmlDoc и занести в нее корневой элемент XML-результата (элемент response), полученного от сервера:

xmlDoc = responseXml. documentElement;

12.8 Создать переменную options_spec и занести в нее первый дочерний элемент корня XML-результата с именем options:

options_spec = xmlDoc. getElementsByTagName("options")[0];

12.9 Удалить все элементы раскрывающегося списка специальностей:

while(spec. options. length)

{

spec. remove(0);

}

12.10 Аналогичным образом удалить все элементы раскрывающегося списка групп.

12.11 Заполнить раскрывающийся список специальностей

12.11.1 Построить цикл по XML-элементам option элемента options со списком специальностей. Для этого ввести инструкцию for и открывающую фигурную скобку цикла:

for(var i=0; i<options_spec. getElementsByTagName("option").length; i++)

{

12.11.2 Создать новый элемент option:

var option = document. createElement('option');

12.11.3 Создать переменную text с текстовым содержимым текущего на итерации цикла элемента option:

var text = options_spec. getElementsByTagName("option")[i].text;

12.11.4 Создать переменную value и занести в нее значение атрибута value текущего на итерации цикла элемента option:

var value = options_spec. getElementsByTagName("option")[i].getAttribute("value") ;

12.11.5 Добавить в созданный в п. 12.11.2 элемент option атрибут value со значением из переменной value:

option. setAttribute('value',value);

12.11.6 Добавить в созданный в п. 12.11.2 элемент option текстовый узел со значением из переменной text:

option. appendChild(document. createTextNode(text));

12.11.7 Добавить созданный в п. 12.11.2 элемент option к элементу spec (списку специальностей):

spec. appendChild(option);

12.12 Аналогичным образом (см. п. 12.8) сформировать переменную options_gr для представления второго элемента options из XML-ответа сервера.

12.13. Заполнить раскрывающийся список групп (см. п. 12.11)

12.14 Ввести закрывающую угловую скобку проверки статуса запроса:

}

12.15 Ввести инструкцию «иначе», выполняющуюся в том случае, когда запрос к серверу был выполнен неудачно:

else

{

alert("Не удалось получить данные от сервера");

}

}

}

13. Создать функцию selSpec, которая должна запускаться при выбора значения из списка факультетов. (см. п. 11). Использовать следующий URL: url = "getListGr. jsp? spec=" + spec;. В качестве функции обратного вызова использовать JavaScript-функцию makeListGr.

14. Создать функцию makeListGr (см. п. 12), формирующую список групп из XML-ответа серверного сценария getListGr. jsp.

15. Открыть файл Index. jsp.

16. Ввести в Index. jsp ссылку на JavaScript-сценарий Ajax. js. Для этого между открывающим и закрывающим тегами элемента HEAD ввести следующий код:

<script type="text/javascript" src="Ajax. js"></script>

17. Добавить в раскрывающийся список факультетов (элемент select с именем faculty) вызов функции selectedFac при изменении выбранного значения списка. Для этого изменить открывающий тег элемента select следующим образом:

<select name="faculty" style="width: 350px" onChange="selectedFac()">

18. Аналогичным образом задать вызов функции selSpec при выборе специальности из раскрывающегося списка специальностей (элемент select с именем spec).

19. Скопировать в папку с веб-приложением файл Browse. jsp из первой лабораторной работы.

19. Проверить работоспособность созданного Web-приложения. Для этого в окне визуальной среды Eclipse выбрать пункт меню

Project → Run as… → Run on Server

5. Контрольные вопросы

1. Каковы недостатки традиционного веб-программирования?

2. Каковы отличительные особенности технологии AJAX?

3. Что представляет собой объект XMLHttpRequest?

4. Что такое функция обратного вызова?

5. Чем отличается статус запроса от состояния запроса?

6. Содержание и оформление отчета

Отчет должен содержать:

– титульный лист, название и цель работы;

– вариант задания;

– листинг программного кода;

– скриншоты результатов работы Web-приложения с различными вариантами запросов;

– выводы по работе.