
- •Iis и xml функции sql Server
- •Поддержка xml в Microsoft sql Server 2000
- •Примеры
- •Iis и xml функции sql Server
- •Шаблоны
- •Запросы xPath
- •Замечания по разделу
- •Возможности ado 2.5 Сохранение и загрузка из файла в формате xml
- •Трансформация с помощью domDocument
- •Выдача Recordset’а в формате xml непосредственно в поток Response
- •Возможности ado 2.6
- •Использование Command для формирования xml-документа на сервере
- •Выполнение шаблона
- •Выполнение запроса xPath
- •Шаблон с агрегатными функциями
- •Формирование xml-документа на клиенте с помощью ado
- •Апдейтаграммы и xml Bulk Load
- •Апдейтаграммы
- •Добавление данных
- •Обновление данных
- •Удаление
- •Создание новой таблицы и загрузка данных
- •Загрузка иерархических документов
- •Заключение
- •Литература
- •Предисловие
- •Настройка iis
- •Содержание wsdl-файла
- •Секция types
- •Секция message
- •Секция portType
- •Формы сообщений
- •Секция binding
- •Секция service
- •Создание Web-методов
- •Тестируем Web-сервис
- •Поддержка sqlxml в .Net Framework
- •Тестовый проект
- •Цели и ограничения
- •Реализация
- •Заключение
- •Литература
- •Тип данных xml Основы
- •Метод query
- •Метод value
- •Метод exist
- •Метод modify
- •Использование xml-типа
- •Хранение xml-типа
- •Поддержка xml Schema
- •Создание схемы
- •Удаление схемы
- •Ограничения текущей реализации
- •Безопасность
- •Вложенные запросы for xml
- •Генерация xsd на лету
- •Поддержка xQuery
- •Тело запроса
- •Конструкторы узлов
- •Операторы сравнения
- •Операторы сравнения атомарных значений
- •Общие операторы сравнения
- •Операторы сравнения узлов
- •Логические операторы
- •Условные выражения
- •Flwor-выражения
- •Кванторные выражения
- •Сортировка
- •Заключение
- •Литература
Реализация
Итак, после создания БД, таблиц и хранимых процедур настала пора настроить виртуальные директории с помощью консоли «IIS Virtual Directory Management for SQLXML 3.0». Зайдите в свойства виртуальной директории srv, на вкладку Security. Необходимо поменять Credentials, под которыми SQLXML будет обращаться к базе данных. В поле User Name введите значение SForumUser, в поле Password – simple. На вкладке Data Source выберите «Use default database for current login». На вкладке Settings выберите опцию «Allow templates».
Теперь необходимо на вкладке Virtual Names настроить виртуальное имя для шаблонов. Я не буду объяснять, как это делается, вся информация содержится в [1].
Следующим шагом будет создание трех Web-методов для виртуального имени webserv: AddUser, AddMessage и IsUserRegistered. Как это сделать, подробно обсуждалось в разделе «Создание Web-методов».
Для создания самого Web-приложения откройте в VS.NET 2003 пункт «New Project», выберете тип проекта Empty Web Project (не важно для какого языка) и введите имя SForum.
Board.htm
Начну с создания главной странички сайта – board.htm. Я не буду приводить здесь ее целиком, выделю лишь ключевые моменты. Для скачивания файла board.xml и board.xslt используются XML-острова (XML islands).
<xml src="http://dcit06/srv/template/board.xml" id="MesSrc"></xml> <xml src="board.xslt" id="xslt"></xml> |
Сами сообщения будут находиться в теге div.
<div id="messages"/> |
Наполнить его содержанием очень просто. Вот код, который выполняется в момент загрузки страницы:
messages.innerHTML = MesSrc.XMLDocument.transformNode(xslt.XMLDocument); |
Для обновления странички сообщений используется несколько более сложный код.
messages.innerHTML = "Подождите..."; var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); xmlhttp.open("GET", MesSrc.src + "?Page=" + curPage + "&PageSize=" _ + mes_per_page.value, false); xmlhttp.send(); MesSrc.XMLDocument = xmlhttp.responseXML; messages.innerHTML = MesSrc.XMLDocument.transformNode(xslt.XMLDocument); |
Сообщения скачиваются с помощью компонента XMLHTTP, при этом в строке запроса передаются следующие параметры: номер запрашиваемой страницы и размер страницы в сообщениях. Первый параметр хранится на страничке как переменная curPage, а второй представлен полем ввода:
<input type="text" id="mes_per_page"> |
Если все сделано правильно, страничка должна выглядеть как на рисунке 6.
Рисунок
6. Страничка board.htm.
Перейдем к следующим страницам.
Login.htm
Обращаться к Web-сервису из браузера мы будем с помощью «поведения Web-сервиса» (Webservice behavior). «Поведение Web-сервиса» – это отдельная очень обширная и сложная тема, которая никак не входит в рамки данной статьи. Если вы не знакомы с этой технологией или имеете смутное представление о методах ее реализации, отправляю вас к MSDN.
«Поведение Web-сервиса» позволяет вызывать Web-методы на клиенте, в коде браузера. Организовав доступ к хранимым процедурам SQL Server-а через Web-методы, можно полностью избавиться от необходимости написания какого-либо серверного кода.
Код «поведения Web-сервиса» находится в файле webservice.htc, который можно скачать по адресу http://msdn.microsoft.com/downloads/samples/internet/behaviors/library/webservice/default.asp. Связать «поведение Web-сервиса» с каким-либо элементом странички можно статически или динамически.
Статическое связывание «поведения Web-сервиса»:
<body> <div id="service" style="behavior:url(webservice.htc)"></div> </body> |
После того как «поведение Web-сервиса» назначено элементу, вы должны связать его с Web-сервисом, при помощи метода useService. Обычно это делается в обработчике onload окна, однако вы вправе связать «поведение Web-сервиса» с Web-сервисом в любой удобный момент.
Связывание «поведения Web-сервиса» с Web-сервисом в обработчике onload:
<script language="JavaScript"> function init() { service.useService("URL","Friendly name"); } </script> <body onload="init()"> <div id="service" style="behavior:url(webservice.htc)"></div> </body> |
С одним «поведением Web-сервиса» можно связать несколько Web-сервисов, главное чтобы их имена, передаваемые во втором параметре, несовпадали.
После этого можно вызывать Web-методы с помощью функции callService. Но прежде чем рассмотреть, как это делается, хочется остановиться вот на чем. Как вы понимаете, вызов любого Web-метода может занять продолжительное время и будет очень плохо, если приложение пользователя, в данном случае – браузер, на это время будет заблокировано. По умолчанию «поведение Web-сервиса» вызывает Web-методы асинхронно. Это значит, что результаты вызова не доступны вызывающей стороне сразу же после того, как метод callService вернул управление. «Поведение Web-сервиса» определяет набор событий, среди которых есть событие onResult, вызывающееся после получения результатов от Web-метода. Так как с одним «поведением Web-сервиса» может быть связано несколько Web-сервисов, а пользователь может одновременно вызывать несколько методов, для идентификации результатов вызова Web-метода вводится специальный счетчик. Он возвращается функцией callService и, как правило, сохраняется в глобальной переменной. В качестве счетчика в примере, приведенном ниже, используется глобальная переменная callid.
Вызов Web-метода
<SCRIPT language="JavaScript"> var callid = 0; function init() { service.useService("URL","MyService"); callid = service.MyService.callService("method"); } function onWSresult() { // Если в процессе вызова возникла ошибка, и это "наш" метод if((event.result.error) && (callid == event.result.id)) { //event.result.errorDetail.code; //event.result.errorDetail.string; //event.result.errorDetail.raw; } // Если ошибки нет, и это "наш" метод else if((!event.result.error) && (callid == event.result.id)) { alert(event.result.value); } // Произошло что-то странное else { alert("Something else fired the event!"); } } </SCRIPT> <body onload="init()"> <div id="service" style="behavior:url(webservice.htc)" onresult="onWSresult()"></div> </body> |
В данном примере, функция callService принимает один параметр – имя Web-метода, однако, вы также можете указывать неопределенное количество параметров, если это требуется. Например, для Web-метода add необходимо два параметра:
callid = service.MyService.callService("add", 1, 10); |
Как видите, в использовании «поведения Web-сервиса» нет ничего сложного.
«Поведение Web-сервиса» обладает большим количеством свойств, и рассмотреть их всех затруднительно, с их помощью вы можете указывать:
Имя пользователя и пароль для Web-сервиса, который требует аутентификации
Порт Web-сервиса
Можете задавать SOAP-заголовки
Устанавливать таймаут и многое другое.
Но вернемся к нашим, как говорится, баранам. Имеется страничка Login.htm, которая содержит поля ввода для имени пользователя и пароля. Необходимо проверить, действительно ли данный пользователь зарегистрирован на сайте. Это делается с помощью Web-метода IsUserRegistered.
Проверка учетной записи пользователя:
function onSubmit() { if (!validateForm()) { ... } else { service.Simplewebserv.callService("IsUserRegistered", NickName.value, psw.value); } } |
Функция onSubmit вызывается при нажатии на кнопку «Вход». Она проверяет корректность введенных пользователем значений и вызывает Web-метод IsUserRegistered с параметрами: имя пользователя и пароль.
Результат анализируется в обработчике события onResult:
function onWSresult() { if (!event.result.error){ var doc = new ActiveXObject("MSXML2.DOMDocument.3.0"); doc.loadXML(event.result.raw.xml); if (doc.parseError.errorCode == 0){ var UserIdNode = doc.selectSingleNode("//sqlresultstream:SqlResultCode"); if (UserIdNode.text == 0){ gen_error.innerText = "Неверное имя пользователя или пароль."; InvalidPsw(); InvalidNickName(); } else{ window.returnValue = "NickName:" + NickName.value + ";UserId:" + UserIdNode.text + ";"; window.close(); } } else{ gen_error.innerText = "Возникла ошибка: " + doc.parseError.reason; } } else{ gen_error.innerText = "Возникла ошибка: " + event.result.errorDetail.string; } } |
Так как SQLXML не использует кодирование RPC, нельзя воспользоваться свойством value объекта result. Вместо этого придется «вручную» проанализировать ответ Web-метода в формате xml. Удобнее всего это сделать с помощью объектной модели документа XmlDOM. Интересующее нас значение, т.е. результат вызова находится в элементе SqlResultCode (см. «XML objects»).
Register.htm
С помощью этой формы производится регистрация пользователя. На ней расположены поля ввода для имени пользователя, пароля и полного имени пользователя (FullName). Для регистрации вызывается метод AddUser.
service.Simplewebserv.callService("AddUser", NickName.value, psw.value, FullName.value); |
В общем, ничего сложного здесь нет. Результат обрабатывается тем же самым образом, что и на страничке login.htm.
Post.htm
Web-метод AddMessage вызывается и обрабатывается схожим образом.