С помощью ASP
программист может быстро создавать
веб-приложения на сервере Windows,
использующем IIS третьей версии (или выше).
ASP вышла в свет в то время, когда между
собой соперничали технологии
программирования Common Gateway Interface
(CGI) и Perl, используемые
многими программистами для разработки
веб-приложений. ASP прекрасно вписывается в
стратегию Microsoft ActiveX, поскольку
обеспечивает функциональность,
инкапсулированную в компоненты COM, и
позволяет разработчикам реализовывать n-звенные
решения с помощью ASP и COM.
Примечание. Листинги кода в этой
лекции доступны на веб-сайте автора
http://mapobject.com/iis6/.
Общая
архитектура ASP
Файлы ASP представляют собой сценарии,
интерпретируемые по мере поступления
запросов. Расширение ISAPI по имени
ASP.DLL
связано в IIS с файлами, имеющими расширения
.asp или
.asa (см. рис.
12.1). ASP.DLL
просматривает файлы .asp на предмет наличия
тегов, обозначающих внедренный код для
выполнения на сервере.
ASP.DLL
передает код сценария в Windows Script Host
(WSH). WSH выполняет этот код и возвращает
ответ файлу ASP.DLL,
который, в свою очередь, передает IIS
результат выполнения сценария и содержимое
самого файла ASP. IIS возвращает ответ
программному обеспечению, от которого
поступил запрос.
ASP.DLL не выполняет обработку
функций подтверждения, написанных на
JavaScript, которые имеются в ASP и
предназначены для выполнения в веб-браузере
или программе, запрашивающей файл ASP.
Примечание. При изложении материала
данной лекции будем считать, что клиент
обращается к программному обеспечению,
запрашивающему файл с веб-сервера.
В стандартных
отношениях сервер/браузер браузер является
клиентом. Клиент отсылает запросы на
веб-сервер, который возвращает запрошенный
файл. Если это файл ASP, то веб-сервер
выполняет некоторые действия перед тем, как
возвратить ответ клиенту. Работа технологии
ASP, как правило, изменяет возвращаемый
клиенту ответ.
Технология
ASP предлагает замечательный механизм
склеивания (glying) различных систем и
программного обеспечения, который позволяет
разработчику легко управлять данными,
поступающими к службам IIS и от них, не
испытывая при этом сложностей, возникающих
при работе с протоколом HTTP и IIS.
Рис. 12.1. Общая архитектура ASP
Предлагаемые
ASP классы обеспечивают хороший уровень
абстракций HTTP- и веб-сервера, что отличает
данную технологию от таких конкурентов, как
Perl и CGI.
В некоторых
случаях бизнес-логика инкапсулируется в
объекты COM. Если COM-объект предоставляет
интерфейс, доступ к которому осуществляется
при помощи VBScript или Jscript, то ASP
функционирует как механизм управления. В
лекции 1 курса "Программирование в IIS"
подробно рассказывается о работе с COM-объектами
в ASP.
Редактирование файлов ASP
Файлы ASP
представляют собой простые текстовые файлы,
поэтому для их создания и правки
используется любой текстовый редактор.
Microsoft Visual Interdev шестой версии
представляет собой утилиту для
редактирования и создания файлов ASP.
Разработчики, как правило, используют другие
программы – TextPad, NotePad (Блокнот) и
даже Dreamweaver. Для редактирования файлов
ASP рекомендуется применять также Visual
Studio .NET.
В данной
лекции для редактирования и создания файлов
ASP используется Visual Interdev. Для
открытия нового файла ASP с помощью Interdev
выполните следующие действия.
-
Откройте программу Visual Interdev.
Появится запрос на ввод имени проекта.
Нажмите Cancel (Отмена) для закрытия
запроса, затем выберите команду File\New
File (Файл\Создать файл).
-
Введите имя создаваемого файла и укажите
его тип.
-
Щелкните на значке ASP File (Файл ASP),
после чего нажмите на кнопку Open (Открыть)
(см. рис. 12.2). Появится окно ASP с
шаблоном кода HTML и инструкцией
обработки в верхней части, которая
означает язык файла VBScript.
Рис. 12.2. Создание нового ASP-файла
в Visual Interdev
VBScript по
умолчанию является языком страниц ASP.
Возможно использование JScript – версии
JavaScript от Microsoft. Однако VBScript
наиболее популярен среди ASP-программистов,
и в этой лекции все рассматриваемые примеры
написаны именно на нем.
Visual
Interdev предлагает разработчикам множество
полезных возможностей, недоступных в других
текстовых редакторах, что делает эту
программу пригодной для выполнения
большинства задач программирования ASP. С
помощью Interdev разработчик может
отлаживать код, выполняющийся на сервере, в
процессе его работы, последовательно
обрабатывая каждую строку программы. Другой
полезной и часто используемой функцией
является Auto List Member (Член автосписка),
которая проверяет правильность синтаксиса,
вводимого программистом. По мере ввода
ключевых слов и команд известных библиотек
Interdev предлагает разработчику правильное
написание команд (см. рис. 12.3).
Рис. 12.3. Функция Auto List Member
(Член автосписка) в Visual Interdev
Если он
нажимает на клавишу (TAB), то Interdev в
этом случае завершает написание команды.
Interdev выделяет цветом фрагменты кода, что
позволяет легко различать команды и
содержимое.
Прекрасным
средством редактирования ASP является Visual
Studio .NET. По возможности работайте с
Visual Studio .NET и вместо ASP используйте
ASP.NET, если нет веских причин отказа от
применения этой технологии (например, ASP
адекватно обслуживает все имеющиеся аспекты,
нуждающиеся в усовершенствовани). В данной
ситуации переделка ASP-файлов в файлы
ASP.NET не принесет пользы. Файлы ASP.NET и
ASP могут выполняться "бок о бок" на сервере
IIS 6, поэтому допустимо внедрять технологии
ASP.NET в программное решение ASP при
возникновении потребности в дальнейшем
усовершенствовании и переходе на технологии
.NET.
Расширения
имен файлов ASP отличаются от расширений
ASP.NET. Файлы ASP.NET имеют расширения
.aspx или
.asa, файлы
ASP – расширения .asp или
.asa. Службы
IIS различают типы файлов по их расширениям
и определяют соответствующее расширение
ISAPI для работы с файлом. Например, если
файл ASP с именем
MyAspFile.asp переименовать в
MyAspFile.aspx,
то при запросе
MyAspFile он будет обработан
технологией .NET, а не с помощью расширения
ASP ISAPI (т.е. файла
ASP.DLL)..
Более
подробно работа с Visual Studio .NET и
ASP.NET показана в лекции 2 курса "Программирование
в IIS".
Примечание. Несмотря на возможность
совместной работы ASP и ASP.NET на одном
веб-сервере, они не могут использовать
общий сеанс, поскольку каждый тип файла
обрабатывается своим программным
обеспечением. Файлы ASP.NET
обрабатываются библиотекой
aspnet_isapi.dll,
которая, в свою очередь, использует для
выполнения кода технологию .NET.
Недостатком
Visual Interdev является то, что эта
программа требует большого количества
ресурсов, поэтому при выполнении простых
задач слишком много времени тратится на ее
открытие. Если разработчику нужно быстро
отредактировать файл, то для этого прекрасно
подойдет программа Notepad (Блокнот) или
Textpad. Visual Interdev является
лицензированным программным продуктом, а это
делает его самым дорогим среди аналогичных
программ.
Настройка
IIS на ASP
Если вы
только что установили сервер или на нем
раньше никогда не применялась технология
ASP, то IIS не будет поддерживать ASP. Для
установки поддержки ASP выполните следующие
несложные действия.
-
Откройте панель управления и выберите
Add Or Remove Programs (Установка и
удаление программ).
- В
левой части окна Add Or Remove Programs
нужно выделить значок Change Or Remove
Programs (Изменить или удалить программы).
После выбора Add Or Remove Windows
Components (Установка компонентов
Windows) откроется мастер компонентов
Windows (Windows Component Wizard).
-
Выберите Application Server (Сервер
приложений) и нажмите на кнопку Details
(Состав).
- В
открывшемся окне Application Server (Сервер
приложений) выберите Internet
Information Services (IIS) и нажмите на
кнопку Details (Состав).
- В
открывшемся окне Internet Information
Services (IIS) выберите World Wide Web
Service (Служба WWW) и нажмите на кнопку
Details (Состав).
-
Отметьте опцию Active Server Pages (см.
рис. 12.4) для установки поддержки ASP.
Рис. 12.4. Установка поддержки ASP в
мастере компонентов Windows
В Windows
Server 2003 и IIS 6 появилась новая функция,
ограничивающая всякую программную поддержку
серверной части по умолчанию и требующая
обязательного наличия поддержки
программирования серверной части.
Запрос на
обработку файла при отсутствии
установленного расширения ISAPI ASP.DLL
выдаст ошибку 404. В предыдущих версиях
Windows Server в IIS это расширение ISAPI
было включено. Данная функция включается на
сервере с помощью административного узла Web
Service Extensions (Расширения веб-служб) в
консоли MMC (см. рис. 12.5). В правой части
окна выберите Active Server Pages, после
чего нажмите на кнопку Allow (Разрешить).
Рис. 12.5. Включение расширения
веб-служб
На веб-сайте
или в виртуальном каталоге необходимо также
установить разрешения на выполнение
сценариев (script). По умолчанию параметр
Execute Permissions (Разрешения на
выполнение) в окне Properties (Свойства)
сайта IIS или виртуального каталога не
включен. Для включения параметра выполните
следующие действия.
-
Откройте консоль IIS MMC и щелкните
правой кнопкой мыши на веб-сайте или
виртуальном каталоге.
- В
контекстном меню выберите Properties (Свойства)
для открытия окна свойств веб-сайта или
виртуального каталога.
- Во
вкладке Virtual Directory (Виртуальный
каталог) окна свойств виртуального
каталога или во вкладке Home Directory (Домашний
каталог) окна свойств веб-сайта в списке
Execute Permissions (Разрешения на
выполнение) выберите Scripts Only (Только
сценарии) (см. рис. 12.6).
-
Нажмите на кнопку OK для закрытия окна.
- После
установки разрешений поместите ASP-файл
на веб-сайт или в виртуальный каталог
для правильного функционирования ASP.
При правильной настройке параметров IIS
выполнение файлов ASP будет происходить
по запросу браузера.
Рис. 12.6. Настройка разрешений на
выполнение для виртуального каталога
Основы ASP
С помощью
объекта Response
код ASP может выполнять запись текста на
клиенте – любого содержимого, включая код,
выполняющийся на клиенте. IIS различает код,
выполняющийся на сервере, и содержимое,
отправляемое клиенту с помощью расширения
ISAPI ASP.DLL, анализируя файл ASP на
наличие начального ("<%") и конечного ("%>")
тега и выполняя код, расположенный между
ними, с помощью WSH.
На рисунке
12.7 показан пример редактирования страницы
ASP с помощью Visual Interdev. На одной и
той же ASP-странице расположены строки
содержимого, записываемые на клиенте с
помощью объекта
Response, и код, выполняемый на
сервере.
Рис. 12.7. Редактирование страницы
ASP с помощью Visual Interdev
Первая строка
кода –
<%@Language=VBScript%> – сообщает
ASP.DLL о том, что необходимо начать поиск
кода для интерпретации. В данном примере для
обработки ASP-страницы установлен язык ASP,
поэтому тег %>
в конце выполняемого кода означает, что все
последующие строки кода должны
игнорироваться, за исключением тега
<%.
Как показано
на рисунке 12.7, если ASP.DLL встречает тег
<% после
строки с тегом <hr>,
то интерпретирует последующие строки кода
вплоть до конечного тега
%>,
расположенного после строки
Response.Write("what
time is it? ->" & now()). Результат
запроса браузером файла
MyAspFile1.asp
(страница ASP на рис. 12.7) показан на рис.
12.8.
Рис. 12.8.
Объекты
ASP
ASP содержит
следующие объекты, обеспечивающих
потребности разработчика в реализации
решения, отвечающего на событие веб-запроса.
-
Объект Response. Используется для
записи данных в запрос HTTP,
возвращаемый клиенту.
-
Объект Aplication. Содержит
параметры и конфигурации по настройке
работы ASP для данного веб-сайта.
-
Объект Request. Хранит содержимое
HTTP-запроса и обеспечивает
вспомогательные функции для обработки
разработчиком данных HTTP-запроса.
-
Объект Server. Содержит информацию о
веб-сервере, веб-сайте, а также
обеспечивает поддержку вызывающего
программного обеспечения.
-
Сеанс. Представляет собой состояние
заданного веб-сеанса с заданным хостом и
клиентом.
Объект
Response
Как и все
объекты ASP, класс объекта Response всегда
доступен коду ASP во время веб-запроса. Этот
объект обеспечивает потребность разработчика
в записи данных на компьютер-клиент во время
выполнения веб-запроса. Функция
Write объекта
Response
возвращает клиенту содержимое переданного ей
аргумента. Объект
Response также позволяет разработчику
контролировать запись данных в HTTP-запрос.
Объект
Application
Объект
Application
используется, в основном, в файле
global.asa для
фиксирования событий приложения ASP.
Объектом Application
фиксируются следующие события.
-
Session_OnStart. Вызывается при
первом запросе пользователя к веб-сайту.
-
Session_OnEnd. Вызывается по
завершении сеанса пользователя.
-
Application_OnStart. Вызывается при
первом запросе пользователем страницы.
-
Application_OnEnd. Вызывается при
отключении IIS.
Объект
Application
также используется для хранения переменных,
не меняющих свое состояние на протяжении
всей работы веб-сайта. Объект
Application
остается активным с момента первого запроса
веб-приложения до момента отключения
веб-сервера, поэтому он используется для
хранения данных, необходимых для всех
запросов на страницы и всех веб-сеансов.
Объект
Request
Объект
Request
реализует для запроса к веб-серверу
получение информации от клиента. В этом
объекте имеется полезный для разработчика
тип данных – данные, отправляемые на сервер.
Например, если требуется имя пользователя,
то ASP запрашивает его у пользователя в
форме с кнопкой Submit (Отправить), которую
пользователь нажимает после ввода данных.
После нажатия кнопки ASP считывает
информацию с помощью объекта
Request. Как
показано в листинге 12.1, объект
Request
использует имя элемента ввода HTML,
содержащего значение, введенное
пользователем.
<%@ Language=VBScript %>
<html>
<head>
<title>What is you name?</title>
</head>
<body>
<FORM METHOD = "POST" ACTION = "askname.asp"
ID = "frmImage"
NAME = "getInfo" >
<%
If len(Request("UserName")) > 0 then
Response.Write("<p>you said your name was: " & _
Request("UserName") & "</p>")
Response.Write("<p>Please reenter it</p>")
else
Response.Write( _
"<p>Please enter you name and click the submit button.</p>")
end if
%>
<input TYPE="text" NAME="UserName"
VALUE="">
<INPUT ID="subFull" NAME="subR"
TYPE="submit" VALUE="Refresh" >
</FORM>
</body>
</html>
Листинг
12.1. AskName.asp - Sample ASP
Requesting User's Name
При первом
запросе пользователем ASP-кода (см. листинг
12.1) ему будет предложено ввести свое имя.
Если пользователь введет произвольный текст
в поле ввода с именем
UserName и нажмет на кнопку отправки
данных, то это значение будет передано на
сервер. Запрос попадет в тот же ASP-код, с
помощью которого создана страница,
отображаемая пользователю. ASP-страница
называется
askname.asp – это видно из атрибута
ACTION
элемента FORM.
При выполнении запроса
askname.asp с
веб-сервера объект
Request используется для считывания
значения в поле ввода с именем
UserName:
Request("UserName")
Библиотеки объекта
Request
Объект
Request
используется для запроса значения из строки
запроса, формы HTTP или элемента
cookie
посредством описанного метода присвоения
имени переменной. Объект
Request
предоставляет разработчику три набора
значений.
-
Request.Cookies. Набор имен и
значений cookie на компьютере клиента.
-
Request.Form. Набор имен и значений
элементов ввода HTML, являющихся
результатом отправки HTML-формы или
записи в файл ASP.
-
Request.QueryString. Набор пар имен
и значений в строке запроса,
используемых для запроса файла ASP.
Все наборы
поддерживают свойства
Count, Key
и Item,
поэтому любой из них позволяет обращаться к
значению с помощью его порядкового номера.
Это целесообразно в случае чтения различных
комбинаций данных с целью определения
способа обработки информации. В ASP можно
встроить логику, согласно которой при
отправке ключа определенного имени будут
найдены и обработаны другие параметры
запроса. В листинге 12.2 приведен пример
кода ASP, осуществляющего вывод всех
значений во всех библиотеках.
<%@
Language=VBScript %>
<%
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'sub WriteCollection
'loops through the contents of any
collection object
'passed in and response.writes the index
and name = value
'using HTML
'
'in
' c = any
1 based collection
' CollectionName
= any string to describe the
' collection
'out – nothing – writes to client
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sub WriteCollection(c, CollectionName)
dim i
'index for collection loop
dim sPhrase
'phrase assembled to show values
'draw a line
Response.Write("<hr><p>")
'announce the size of the collection
Response.Write(CollectionName & " have " & c.Count & _
" values:</p>")
for i= 1 to c.Count
'these collections are 1
based -
'I don't know why when
most all others are 0 based
sPhrase = "#" & i & " " &
c.Key(i) & _
" = " & c.Item(i) & "<br>"
Response.Write(sPhrase)
next
end sub
%>
<HTML>
<HEAD>
<META NAME="GENERATOR"
Content="Microsoft Visual Studio 6.0">
<title>Tell me about the
requester</title>
</HEAD>
<BODY>
<%
'show me the server time so I can verify
page is not cached
Response.Write("<p>server time: " &
now() & "</p>")
'write cookies collection
WriteCollection Request.Cookies,
"Cookies"
'write form variables collection
WriteCollection Request.Form, "Form
Variables"
'write query string collection
WriteCollection Request.QueryString,
"Query String"
%>
</BODY>
</HTML>
Листинг
12.2. ShowRequestValues.asp - ASP
Listing Collection Contents
В листинге
12.2 приведена подпрограмма
subWriteCollection(c,CollectionName),
считывающая аргумент набора и выводящая в
браузере, выполняющем запрос, имена и
значения всех элементов набора. Номера
набора должны начинаться с единицы, а не с
нуля, как в других наборах. Подпрограмма
WriteCollection
вызывается трижды из раздела
BODY раздела
HTML. При
каждом вызове в подпрограмму передается
набор объекта Request.
При выполнении файла ASP
ShowRequestValues.asp
(см. листинг 12.2) на экран выводятся
демонстрационные значения элементов cookie и
строк запросов (см. рис. 12.9).
Рис. 12.9. Вывод наборов запроса
Два элемента
cookies на компьютере-клиенте вывели
результат запроса файла
ShowRequestValues.asp
в следующие строки браузера:
#1 TheServer =
Name=birdhouse&Number=2
#2 Visits = LastTime=3%2F22%2F2003+8%3A55%3A02+AM
Один элемент
cookie называется
TheServer, а другой –
Visits.
Элемент cookie
TheServer имеет несколько значений,
поэтому его имя равно параметру
Name, который,
в свою очередь, равен значению
birdhouse. Это
следует из того, что значение свойства
Key набора
Request.Collection
является именем элемента cookie, а значением
свойства Item
набора элементов cookie является пара имя/значение.
Наборы Request.Form
и Request.QueryString
состоят лишь из пар имя/значение,
содержащихся в значениях свойств
Key и
Item
соответственно.
Управление
кэшированием содержимого с помощью
заголовков HTTP
Браузеры
периодически выполняют кэширование
веб-страницы или ее части. Время сервера
было записано в браузер (см. листинг 12.2)
для определения того, кэшировались ли
результаты работы файла
ShowRequestValues.asp.
Кэширование содержимого улучшает
производительность веб-сайта; тем не менее,
в отдельных случаях его использовать
нежелательно. Некоторые браузеры не могут
переписать новые данные из кода ASP или
отобразить нужное изображение, если имена
этих элементов совпадают с именами файлов,
кэшированных из предыдущего запроса с того
же сервера, а изображение изменилось со
времени предыдущего запроса. С помощью
команды AddHeader
объекта Response
можно добавить аргумент в запрос HTTP,
отправляемый к запрашивающему браузеру, и
запретить кэширование содержимого на
странице. При считывании запроса HTTP
браузер находит заголовок, обозначающий, что
содержимое должно быть загружено, а не
получено из кэша браузера.
В листинге
12.3 приведен пример заголовков, добавляемых
в верхнюю часть файла ASP, для запрета
веб-браузеру отображения кэшированного
содержимого.
<%@
Language=VBScript %>
<%
'eliminate caching
Response.AddHeader "pragma","no-cache"
Response.AddHeader "cache-control","private"
Response.CacheControl = "no-cache"
%>
Листинг
12.3. Использование функции AddHeader
Этот же
результат можно получить более простым
способом, добавив на страницу строку
Response.Expires=-1.
Управление
состоянием приложения посредством элементов
cookie
Элементы
cookie позволяют хранить данных о состоянии
на хосте веб-браузера. Данные могут быть
получены позже с компьютера пользователя.
Запись элементов cookie осуществляется
посредством функции
Response.Cookies. В листинге 12.4
показан код ASP для вывода имеющихся
элементов cookie и их обновления. Элементы
cookie можно записать с указанием срока
действия. Если срок действия не указан, то
они существуют до тех пор, пока пользователь
не закроет браузер. После этого элементы
cookie удаляются с компьютера, на котором
работал браузер.
<%@
Language=VBScript %>
<%
'need to do this because we are writing
cookies
Response.Buffer = True
%>
<!--#include file="CommonSubs.inc"-->
<HTML>
<HEAD>
<title>Let me mark the time you were
here last</title>
</HEAD>
<BODY>
<p> Here are the cookies that were here
before </p>
<%
'write cookies collection
WriteCollection Request.Cookies,
"Cookies"
'get time and date for right now
dim sTimeNow
sTimeNow = now()
'get previous number
dim sCookie
dim i
'get cookie value
sCookie = Request.Cookies("TheServer")("Number")
'make it a number and increment
i = cint(sCookie) + 1
%>
<hr>
<p> The Visits cookie LastTime value
will be updated to
<% =sTimeNow %> </p>
<p> The TheServer cookie Number value
will be updated to
<% =i %> </p>
<%
'update cookie values
Response.Cookies("Visits")("LastTime") =
sTimeNow
Response.Cookies("TheServer")("Name") =
"birdhouse"
Response.Cookies("TheServer")("Number")
= i
%>
</BODY>
</HTML>
Листинг
12.4. WriteCookies.asp - ASP Listing and
Updating Cookies
В листинге
12.4 показан код ASP-файла
WriteCookies.asp
для считывания и записи элементов cookie при
каждом вызове файла. Их значения считываются
посредством набора
Request.Cookies и записываются в
браузер с помощью подпрограммы
Write.Collection,
в результате чего конечный пользователь
видит эти значения. После этого ASP
считывает значение
Number элемента cookie
TheServer и
прибавляет к нему единицу. Это новое
значение и значение
LastTime элемента cookie
Visits
записываются с помощью команды
Response.Cookies(<имя
cookie>) (<имя параметра>)=<новое значение>.
После блока кода спецификации языка в
листинге 12.4 расположена строка
Response.Buffer=True.
Эта команда выполняет проверку того, что
сконструирован весь HTTP-запрос, включая
заголовки и содержимое, перед его записью в
браузер клиента. Если страница,
предназначенная для отправки браузеру,
полностью сконструирована, то
ASP.DLL
сначала отправляет заголовки, необходимые
для установки элементов cookies, а затем –
само содержимое. Заголовки нужно записывать
перед отправкой содержимого по причине
определенных ограничений HTTP. Если параметр
буфера объекта
Response не включен, то содержимое
будет передаваться клиенту потоком по мере
генерирования, без передачи заголовков. В
листинге 12.4 показано также использование
файла включения. В строке 7 команда
<!--#include file="CommonSubs.inc"-->
вставляет содержимое файла
CommonSubs.inc
в файл ASP, как если бы оно было введено
вручную в указанном месте файла.
Подпрограмма
WriteCollection (см. листинг 12.2)
размещена в файле
CommonSubs.inc. Большим преимуществом
файла включения является то, что в одном
файле можно расположить множество общих
функций для использования другими файлами в
рассматриваемом веб-приложении без
повторного ввода кода. Наличие единственной
копии кода, используемого файлами ASP,
значительно облегчает работу по сравнению с
ситуацией, когда в коде каждого файла
приходится создавать отдельную версию одной
и той же функции или подпрограммы.
Исправление ошибки в файле включения
устраняет эту ошибку одновременно из всех
файлов, использующих данное включение. Если
во ASP-файлах используются отдельные копии
одной и той же функции или подпрограммы, то
исправление ошибки потребует большого объема
работы, а также возникнет риск появления
новых ошибок.
В листинге
12.4 показан еще один подход ASP,
заключающийся в использовании знака
равенства "=" для выполнения
Response.Write.
Речь идет о следующей строке:
<p> The Visits
cookie LastTime value will be updated to
<%
=sTimeNow %> </p>
Фрагмент кода
<% =sTimeNow %>
открывает блок кода ASP в секции
HTML страницы
ASP, достаточно длинный для записи значения
переменной sTimeNow.
Знак "="
является сокращенным представлением команды
Response.Write
сразу после тега <%.
Данный подход используется, если нужно
вставить команду
Response.Write в код HTML и, в то же
время, обеспечить простоту работы и
удобочитаемость кода.
Объект
Session
Объект
Session
представляет собой готовое средство
управления состоянием с помощью элементов
cookie. Объект
Session управляет временем сеанса и
информацией о конечном пользователе,
запрещая программисту считывать и записывать
значения элементов cookie и времени проверки
для сеанса. Если компьютер клиента не
разрешает использование элементов cookie, то
объект Session
не сможет записать сеансовый элемент cookie
и будет функционировать неправильно. Элемент
cookie, записываемый объектом
Session, не
имеет срока действия, поэтому он удаляется
при закрытии браузера. Объект
Session
содержит все данные сеанса в наборе
Session.Contents.
Объектом Session
и набором Contents
управляют так же, как и другими наборами
объектов ASP.
WriteCollection (особая подпрограмма
в листинге 12.2) используется для
отображения содержимого набора
Session.Contents
точно так же, как при записи элементов
cookie, переменных формы и наборов
QueryString в
браузер. В листинге 12.5 приведен пример
кода, в котором объект
Session
используется аналогично набору
Request.Cookies.
<%@
Language=VBScript %>
<!--#include file="CommonSubs.inc"-->
<%
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'sub UpdateSession
'Performs a simple Session object read
and write
'
'obtains the current time and the
previous Session
'value for Number. The value for Number
is incremented.
'All new values are written to the
Session.
'
'in
' oSession
= any 1 based collection - specifically
' Session Object
' NewTime = new
time generated written to Session
' NewNumber =
new number written to Session
'
'out - nothing - writes to client.
' NewTime,
NewNumber are updated.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sub UpdateSession(oSession, NewTime,
NewNumber)
dim sSession
'get time and date for right now
NewTime = now()
'get session value
sSession = oSession("Number")
'make it a number and increment
NewNumber = cint(sSession) + 1
'write the new values
oSession("Number") = NewNumber
oSession("LastTime") = NewTime
oSession("Name") = "birdhouse"
end sub
%>
<HTML>
<HEAD>
<title>managing a session using the
session object</title>
</HEAD>
<BODY>
<p> Here is the session prior to
update</p>
<%
dim sTime
dim sNumber
'write Session collection
WriteCollection Session.Contents ,
"Session Contents"
'write some other sundry values
Response.Write("<br>Session.SessionID:"
& Session.SessionID)
Response.Write("<br>Session.Timeout:" &
Session.Timeout)
'update session and get new values that
are written to session
UpdateSession Session.Contents, sTime,
sNumber
'set session timeout to 1 minute -
default is 20 minutes
Session.Timeout=1
%>
<hr>
<p>The session LastTime value will be
updated to <% =sTime %></p>
<p>The session Number value will be
updated to <% =sNumber %></p>
</BODY>
</HTML>
Листинг
12.5. ReadWriteSession.asp - ASP Page
Using the Session Object
Листинг 12.5
представляет собой код ASP, выполняющий
считывание значения объекта
Session,
обновление значения и запись новых значений
в объект Session.
Подпрограмма
WriteCollection представляет собой
файл включения, указанный в строке
<!--#include file="CommonSubs.inc"-->.
Два других свойства, уникальных для объекта
Session –
SessionID и
Timeout –
записываются в браузер. Подпрограмма
UpdateSession
вызывается с помощью набора
Session.Contents
с использованием в качестве аргументов
переменных sTime
и sNumber.
Переменные sTime
и sNumber
являются пустыми переменными, которым
присваиваются значения сеанса в подпрограмме.
После установки значения
Session.Timeout,
равного 1 минуте, в браузер записывается
информация об обновлениях, внесенных в сеанс.
В VBScript по
умолчанию все параметры в функции или
подпрограмме передаются по обращению. Это
значит, что значения аргументов примут в
результате работы функции или подпрограммы
значения переданных аргументов. В
подпрограмме
UpdateSession переменным
sTime и
sNumber не
присвоено значений при их передаче в
UpdateSession
в качестве аргументов. В подпрограмме
значение переменной
sTime устанавливается равным текущему
времени с помощью функции
now(), а
переменной sNumber
– предыдущему значению, к которому
прибавляется единица. После завершения
подпрограммы обе переменные
sTime и
sNumber
содержат новые значения, присвоенные им
функцией
UpdateSession. Если перед любым
параметром в объявлении прототипа
подпрограммы расположить ключевое слово
byval, то
передаваемый аргумент не будет изменяться
после завершения подпрограммы.
При первом
выполнении кода ASP в файле
ReadWriteSession.asp
(см. листинг 12.5) в браузере отображаются
значения объекта
Session. Параметр
Session.Timeout
по умолчанию равен 20, и в сеансе не
устанавливаются никакие значения до тех пор,
пока ASP не завершит свое выполнение. На
рисунке 12.10 показаны результаты первого
выполнения сеансового кода ASP.
Рис. 12.10. Выходные данные сеанса
по умолчанию
Обновление
файла
ReadWriteSession.asp вызывает
повторное выполнение кода ASP и обновление
сеансового объекта посредством присвоения
новых значений, а также вывод значений в
браузер (см. рис. 12.11). Объект
Session может
содержать значения, ассоциированные с именем,
подобно элементам cookie, что позволяет
использовать его в качестве механизма
управления состоянием приложения между
запросами страницы. Элементы cookie (см. рис.
12.9) добавлены в объект
Session для
демонстрации аналогии хранения и получения
данных с помощью сеанса и элемента cookie.
Файл
ReadWriteSession.asp также
устанавливает новое значение
Session.Timeout,
равное 1 минуте.
Рис. 12.11.
Ограничения объекта
Session
Объект
Session имеет
некоторые ограничения, с которыми необходимо
ознакомиться, прежде чем реализовывать
управление состоянием с помощью ASP на базе
объекта Session.
Сеанс не повторяется и не является общим
между серверами, работающими в так
называемой веб-ферме.
Данные сеанса
хранятся непосредственно на несущем сервере,
инициировавшем сеанс. При первом запросе
пользователем ASP-страницы с помощью сеанса
ASP на хост клиента записывается сеансовый
элемент cookie. Сеансовый cookie содержит
единственное значение, выступающее в роли
ключа. При запросе другой ASP-страницы
библиотека ASP.DLL
получает сеансовый элемент cookie и
просматривает данные, которые будут
присвоены объекту
Sesion, с помощью ключа, полученного
из сеансового cookie. Если страница ASP
обслуживается другим веб-сервером, входящим
в состав веб-фермы, то данные сеанса
веб-сервера, на котором создан элемент
cookie, на этом хосте отсутствуют, и сеанс
не будет загружен.
При
использовании объекта ASP
Session в его
первоначальном виде можно задействовать
только один сервер. Решение этой проблемы
заключается в создании и использовании
сеансового сервера, управляющего данными
сеанса для веб-серверов – членов веб-фермы.
Хосты, являющиеся членами веб-фермы, по мере
необходимости могут получать данные сеанса
запрашивающих сторон от сеансового сервера.
Подробный рассказ об этом подходе не входит
в данную книгу, однако вам следует
обязательно ознакомиться с ним, если в
веб-ферме применяется ASP-конструкция с
объектом Session.
ASP.NET предлагает более простое решение,
представляющее собой внутреннюю часть этой
технологии; о нем мы расскажем в лекции 2
курса Программирование в "IIS".
Объект
Server
ASP часто
используется для получения данных из
хранилища информации, применения к ним
некоторой бизнес-логики и отображения
информации в браузере. Все эти задачи можно
выполнить с помощью ASP, однако многие
веб-программисты используют для этой цели
другие программные библиотеки. ASP не
содержит внутренней библиотеки для
считывания источников данных, тем не менее,
объект Server поддерживает функцию создания
экземпляра объекта COM. Экземпляром объекта
является любой объект COM с интерфейсом,
который можно считать с помощью VBScript.
Распространенный объект COM или набор
объектов для считывания данных из источников
называется Active Data Objects (ADO).
Доступ к данным с
помощью ADO
Целью
разработки технологии ADO является
предоставление разработчику универсального
решения относительно доступа к данным для
всех источников информации. В идеальном
случае ADO выступает в роли абстракции между
кодом бизнес-логики и источником данных
любого вида. Изменяя набор параметров,
указывающих на расположение источника данных,
программа продолжает считывать и записывать
данные в источник без корректирования кода.
В настоящее время ADO обеспечивает такой тип
абстракции между источниками данных с
аналогичной структурой данных. Например, код
ADO, используемый для считывания и записи
данных в базу данных SQL Server, позволяет
производить те же самые действия с
информацией в базе данных Oracle без
изменения кода.
Наследование технологий доступа к данным.
Microsoft выпустила также такие библиотеки
доступа к данным, как Data Access Objects
(DAO) и Remote Data Objects (RDO). DAO
реализует великолепную возможность
управления и обработки программистом набора
данных, извлеченных из базы данных, однако
не позволяет выполнять асинхронный запрос
базы данных "клиент-сервер", расположенной
на сервере. RDO имеет более скромные
возможности обработки и управления данными,
полученными из базы данных, но при этим
содержит несколько программ, позволяющих
эффективно извлекать данные из базы данных
типа "клиент-сервер", находящейся на сервере.
Обе технологии считаются устаревшими, в
настоящее время не поддерживаются, и
использовать их не следует. ADO дает
программисту оптимальные решения в любых
ситуациях; эта технология стала основной
технологией для доступа к данным Microsoft.
ADO имеет множество функций по управлению и
обработке данных, извлеченных из базы данных,
а также по подключению к базе данных.
Использование ADO в ASP. Код ASP,
осуществляющий доступ к базе данных для
отображения набора записей, должен
использовать команду
Server.CreateObject для реализации
технологии ADO. Все COM-объекты имеют имена
и зарегистрированы на несущем сервере. Имена
COM-объектов исключают проблемы, связанные с
нахождением нужной библиотеки, посредством
абстрагирования ее расположения на узле от
работы по обращению к библиотеке. Объект COM
указывается только по его имени. Команда
Server.CreateObject
использует имя объекта COM в виде
<имя библиотеки>.<имя
класса> в качестве аргумента функции.
Экземпляр объекта COM возвращается
переменной, установленной на вызов функции.
ADO
представляет собой группу объектов COM,
поэтому команда
Server.CreateObject используется при
создании различных объектов для подключения
к базе данных, считывании из нее наборов
записей и передачи этих значений в браузер.
В листинге 12.6 показан демонстрационный код
ASP, осуществляющий считывание простого
набора записей из таблицы базы данных и
передающий данные в браузер.
<%@
Language=VBScript %>
<HTML>
<HEAD>
<title>read a database table</title>
</HEAD>
<BODY>
<%
dim myConn
dim myRecordset
dim sSQL
dim sResult
dim sConn 'For database connection
string
'create connection string
sConn = "Provider=Microsoft.Jet.OLEDB.4.0;"
sConn = sConn & "Data Source=C:\aspData\employees.mdb;"
'establish connection
Set myConn = Server.CreateObject("ADODB.Connection")
myConn.Open sConn
'create the recordset
set myRecordset = Server.CreateObject("ADODB.Recordset")
'build SQL command
sSQL = "SELECT first_name, last_name FROM tblEmployee"
'open the recordset from the database
myRecordset.Open sSQL, myConn
'check if there are any values in the recordset
if not( myRecordset.EOF and myRecordset.EOF) then
'loop through the
recordset until the end record
while(not myRecordset.EOF)
'build output string
sResult = myRecordset("first_name") & "
"
sResult = sResult & _
myRecordset("last_name") & "<br />"
'write value to browser
Response.write(sResult)
'advance recordset
myRecordset.moveNext()
wend
else
'let us know that there
were no values
Response.write("nothing
returned")
end if
'shut down recordset and connection objects
myRecordset.Close()
myConn.Close()
%>
</body>
</html>
Листинг
12.6. readDB.asp - ASP Opening a
Recordset from a Database and Printing
the Contents to the Web Browser
Объект
подключения ADO. Первым объектом,
создаваемым в коде листинга 12.6, является
объект подключения ADO. Библиотеке ADO
присваивается имя
ADODB, а в качестве имени класса
используется "Connection". Таким образом,
команда создания объекта выглядит следующим
образом:
Set myConn =
Server.CreateObject("ADODB.Connection")
Переменная
myConn
указывает на экземпляр класса ADO
Connection.
Класс Connection
осуществляет хранение и передачу данных
доступа к источнику данных. В листинге 12.6
строка Object Linking and Embedding database
(OLE для баз данных) (OLE-DB) открывает
подключение к базе данных Microsoft Access,
расположенной на сервере.
База данных
Microsoft Access. Использование базы данных
Microsoft Access на одном узле с
веб-сервером является хорошим способом
быстрого доступа к данным при работе с
небольшими наборами данных (размер которых
не превышает 300 Мб). Уровень
производительности в зависимости от размера
набора данных может сильно меняться в
зависимости от узла и приложения, поэтому
нужно загружать тест для определения предела
производительности. Использование файла базы
данных Access не влияет на
производительность, но для управления
данными таким способом (не с помощью команд
SQL в коде ASP) придется приобрести
программу Microsoft Access. Microsoft Access
обеспечить более быстрый доступ к данным при
работе с небольшими наборами данных в
отличие от дорогостоящих СУБД типа Microsoft
SQL Server или Oracle.
Тем не менее,
Microsoft Access имеет множество ограничений
при управлении большими наборами данных.
Microsoft Access не обеспечивает
функциональных возможностей SQL Server и
Oracle. Эта программа представляет собой
популярную утилиту чтения и записи файлов,
поскольку ресурс, из которого запрашиваются
данные, предоставляется
приложением-потребителем. В ASP ресурс
данных для запроса предоставляется IIS. Тем
не менее, прямо противоположным случаем
является база данных уровня предприятия, при
работе с которой источник данных для запроса
ограничивается узлом. Разрешения на доступ к
базе данных Microsoft Access устанавливаются
настройкой файловых разрешений. В примерах,
приводимых в данной лекции, учетной записи
службы IIS с именем
IUSER_<имя компьютера> (где
имя компьютера
– это имя узла) нужно предоставить
разрешения на чтение и запись в файл базы
данных Microsoft Access
.mdb. Файл
Microsoft Access имеет расширение
.mdb и
определяется в строке подключения OLE-DB.
Объект
набора записей ADO. В рассматриваемом
процессе участвует еще один объект ADO с
именем recordset
– объект набора записей. С его помощью
программист осуществляет доступ к информации
в наборе данных, их чтение и запись в
источник. Набор записей открывается с
помощью команды SQL и экземпляра объекта
подключения MyConn.
После вызова функции Open объекта набора
записей этот набор можно считать и записать
в браузер. Однако предварительно его нужно
проверить на наличие в нем записей. Набор
является пустым, если оба условия – BOF (начало
файла) и EOF (конец файла) – принимают
значение true
(истина). При первом открытии
подразумевается, что набор записей указывает
на первую запись. Переход к следующей записи
в наборе выполняется с помощью функции
moveNext
объекта recordset.
При каждом вызове команды moveNext нужно
проверять условие EOF. Если условие EOF
истинно, то выполнен переход к концу файла.
Выполнение команды
moveNext по достижении условия EOF
вызовет ошибку. Пока условие EOF не является
истинным, в наборе записей можно выполнять
переход к следующей записи. После завершения
работы с базой данных объекты набора записей
и подключения необходимо закрыть.
Результатом
выполнения кода (см. листинг 12.6) является
отображение в браузере имени, пробела и
фамилии из каждой записи в таблице
tblEmployee
базы данных. Файл ASP можно
усовершенствовать для реализации отправки
конечным пользователем информации в таблицу
с данными. В листинге 12.7 приведен фрагмент
ASP-кода (ReadWriteDB.asp),
отображающий данные из таблицы
tblEmployee,
который позволяет пользователю отправить
дополнительные данные для записи в базу
данных.
<HTML>
<HEAD>
<title>read and write to a database
table</title>
</HEAD>
<BODY>
<%
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'main entry point to ASP
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dim myConn 'For ADO connection
dim sSQL 'For SQL command
dim sConn 'For database connection
string
'create connection string
sConn = "Provider=Microsoft.Jet.OLEDB.4.0;"
sConn = sConn & "Data Source=C:\aspData\employees.mdb;"
'establish connection to database server
Set myConn = Server.CreateObject("ADODB.Connection")
myConn.Open sConn
'get parameters from user submission
AddData myConn
'build SQL command to show what exists in database
sSQL = "SELECT * FROM tblEmployee"
'show the data
ShowUserRecordset sSQL, myConn
%>
<FORM METHOD = "POST" ACTION = "ReadWriteDB.asp"
ID = "frmFields" NAME = "getInfo" >
<%
'build the data entry table
MakeDataEntryTable sSQL, myConn
'close up connection since we are done
myConn.Close()
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'End of ASP
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%>
<INPUT ID="subFull" NAME="subR"
TYPE="submit" VALUE="Add" >
</FORM>
</body>
</html>
Листинг
12.7. Part of ReadWriteDB.asp Showing
Main Entry Point of ASP
Файл
ReadWriteDB
содержит еще три подпрограммы, которые
исключены из листинга 12.7 для сокращения
его объема. Листинг 12.7 показывает главную
точку входа ASP-кода
ReadWriteDB, в которой расширение
ISAPI ASP.DLL
начинает выполнять код серверной части.
Дополнительными подпрограммами файла
ReadWriteDB.asp,
исключенными из листинга 12.7, являются
следующие:
-
sub ShowUserRecordset. С помощью
команды SQL и переданного экземпляра
объекта ADO
Connection подпрограмма выводит
содержимое набора записей в браузере;
-
sub MakeDataEntryTable. С помощью
команды SQL и переданного экземпляра
объекта ADO подпрограмма выводит таблицы
с именами полей в качестве заголовков и
передает браузеру данные о полях;
-
sub AddData. Подпрограмма проверяет
объект Request
на предмет отправки данных и вставляет
переданные пользователем данные в
таблицу базы данных с именем
tblEmployee.
Запись данных из
формы в базу данных: sub AddData
После блока
комментариев "main
entry point to the ASP" ("главная
точка входа в ASP") код ASP инициирует
объект ADO подключения к базе данных и
присваивает переменную
myConn точке
объекта. Подключение ADO передается всем
подпрограммам, чтобы они могли создавать
свои собственные объекты ADO и подключать их
к источнику данных. После создания объекта
подключения вызывается подпрограмма
AddData (см.
рис. 12.8) для проверки данных, передаваемых
в ASP.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'sub AddData
'Checks Request Object for data
submission and inserts
'the user submitted data into the
database table
'tblEmployee
'
'in
' oConnection =
ADO connection object
'out - nothing - writes to client
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sub AddData(byval oConnection)
'check for data to write
if ((len(Request("number"))< 1) or _
(len(Request("phone"))< 1) or _
(len(Request("first_name"))< 1) or _
(len(Request("last_name"))< 1)) then
exit sub
end if
dim myCommand
dim sSQL
'create the Command object
set myCommand = Server.CreateObject("ADODB.Command")
set myCommand.ActiveConnection = oConnection
'build the insert statement
sSQL = "INSERT INTO tblEmployee ("
sSQL = sSQL & "[number], [phone], [first_name], [last_name])"
sSQL = sSQL & " VALUES ('" & Request("number")
sSQL = sSQL & "','" & Request("phone")
sSQL = sSQL & "','" & Request("first_name")
sSQL = sSQL & "','" & Request("last_name")& "')"
'put the command in the command object
myCommand.CommandText = sSQL
'execute the query
myCommand.Execute
end sub
Листинг
12.8. Part of ReadWriteDB.asp - AddData
Subroutine Writing Data to Database
В
подпрограмме AddData
объект Request
проверяется на наличие ожидаемых параметров
– number,
phone,
first_name и
last_name. При
отсутствии любого из параметров подпрограмма
завершает работу. Наличие параметров
определяется проверкой длины параметра. Если
все параметры имеют длину, равную хотя бы
одному символу, объект команды ADO
присваивается.
Использование объекта Command. Объект
ADO Command
используется в командах SQL или в других
задачах, когда команда передается на сервер
базы данных, но ответ набора записей
требуется не всегда. Объект
Command
возвращает набор записей, но, как в нашем
примере, команда SQL
Update передается базе данных для
выполнения. Команда SQL создается
посредством конкатенации всех частей строки,
необходимых для генерирования выражения
обновления SQL, имеющего примерный вид:
INSERT INTO
tblEmployee ([number],[phone],[first_name],[last_name])
VALUES ('8','444-4444','Tosa','Bergstaff')
Значения в
секции VALUES
команды SQL извлекаются из объекта
Request. После
ассемблирования команда SQL помещается в
параметр CommandText
объекта Command
и обрабатывается с помощью функции
Execute
объекта Command.
В случае успешного выполнения значения
запишутся в базу данных. Ошибка означает,
что некоторый элемент, участвующий в
транзакции с базой данных (например, сервер)
отсутствует или определен некорректно. Такая
ошибка возникает из-за проблем с сетевыми
подключениями либо из-за того, что
разработчик неправильно указал имя таблицы
или поля в коде.
Приемы
программирования и программирование "вручную".
Подпрограмма AddData
имеет ограниченный набор функций, поскольку
для нее задается имя таблицы, которое она
обновляет, и имена параметров, запрашиваемые
из объекта Request.
Разработчики называют такой подход
программированием "вручную", а значения
называются магическими значениями или
литералами. Как правило,
программирование вручную реализуется для
рационального и надежного выполнения, однако
лучше его избегать. Литералы, зависимые от
конкретной реализации приложения, нужно
заменить и установить как параметры
конфигурации приложения, которое можно
откорректировать без редактирования кода.
Считывание
информации из базы данных для отображения в
браузере: sub ShowUserRecordset
После записи
отправленной в базу данных информации
ReadWriteDB.asp
создает команду SQL для чтения всех данных
из таблицы
tblEmployee. Команда SQL
присваивается переменной sSQL. Объект
подключения MyConn
и команда SQL sSQL передаются подпрограмме
ShowUserRecordset.
Оба аргумента передаются
byval, поэтому
их значения в подпрограмме изменить нельзя.
ShowUserRecordset
принимает команду SQL и объект ADO
Connection,
открывает набор записей по команде SQL и
записывает значения этого набора в браузер.
Изучите код подпрограммы
ShowUserRecordset,
приведенный в листинге 12.9.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'sub ShowUserRecordset
'Using the SQL command and the
Connection object
'instance passed in, prints the contents
of the
'recordset to the browser
'
'in
' sSQL =
SQL command for recordset
' oConnection =
ADO connection object
'out - nothing - writes to client
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sub ShowUserRecordset(byval sSQL, byval
oConnection)
dim myRecordset
dim sResult
dim oField
'create the recordset
set myRecordset = Server.CreateObject("ADODB.Recordset")
myRecordset.Open sSQL, oConnection
'write out the headings
for each oField in myRecordset.Fields
sResult = sResult &
oField.Name & "
"
next
Response.Write(sResult & "<br/>" )
'check to see if there are records
if( not myRecordset.EOF and not myRecordset.EOF) then
'make certain that we are
not at the end
while(not myRecordset.EOF)
'build output string
sResult=""
for each oField in myRecordset.Fields
sResult = sResult &
myRecordset(oField.Name) & " "
next
sResult = sResult & "<br />"
'write value to browser
Response.write(sResult)
'advance recordset
myRecordset.moveNext()
wend
else
Response.write("No
records in table <br>")
end if
Response.write("<hr>")
'shut down recordset and connection objects
myRecordset.Close()
end sub
Листинг
12.9. Part of ReadWriteDB.asp -
ShowUserRecordset Subroutine Reading
Database and Showing Recordset
Методы ADO
прохода по набору записей. Подпрограмма
ShowUserRecordset
в листинге 12.9 работает лучше, чем
AddData,
поскольку команда SQL передается в
подпрограмму вместо ручного ввода. После
создания и открытия экземпляра набора
записей ADO при помощи кода SQL, переданного
посредством параметра sSQL, имена полей
набора записей выводятся в строковую
переменную sResult.
Переменная sResult
предназначена для сбора текста,
передаваемого браузеру командой
Response.Write.
Набор записей ADO поддерживает набор
Fields,
содержащий все поля, формирующие набор
записей. Для циклового прохода через все
поля в наборе в подпрограмме
WriteCollection
использован прием, показанный в листинге
12.2. В качестве значения индекса в цикле
For...Next
используется следующая форма псевдокода:
For each <variant>
in <a collection>
Все
переменные в VBScript имеют тип
variant,
поэтому любая объявленная переменная может
выступить в роли переменной индексирования
набора. Переменная
oField является индексом в цикле
For...Next,
используемом для доступа к коллекции
Fields набора
записей MyRecordset
в подпрограмме
ShowUserRecordset. После записи в
браузер результирующей строки имен полей
набор записей проверяется на наличие записей,
и выполняется цикл
While...Wend, осуществляющий проход
по записям. В цикл
While...Wend включен еще один цикл
For...Next,
использующий набор полей
MyRecordSet.
Цикл Fields
Collection указывает имя поля в
наборе записей для получения значения,
присоединяемого к строке
sResult.
Результатом каждой итерации цикла
While...Wend
является одна строка из открытого набора
записей, записываемая в браузер.
Примечание. Многие программисты с
опытом написания программ при выполнении
прохода по набору записей довольно часто
допускают одну ошибку – они забывают
переходить к следующей записи в наборе.
Строка
myRecordset.moveNext() в листинге
12.9 выполняет такой переход. Это
довольно распространенная ошибка, так
как команда
moveNext() не требует больших
интеллектуальных затрат от программиста.
Стратегия элемента настолько проста, что
разработчик просто забывает включить
этот элемент в код.
После
продвижения по набору записей и передачи его
браузеру этот набор нужно закрыть с помощью
команды close()
объекта recordset.
Экземпляр набора записей уничтожается, если
переменная, указывающая на экземпляр
myRecordset,
выходит за рамки области действия. Это
происходит при завершении работы
подпрограммы
ShowUserRecordset. Тем не менее, мы
не рекомендуем полагаться на ресурсы,
освобождаемые при выходе переменной из
области действия, так как это происходит не
всегда при отключении подобным образом. Для
закрытия подключения к базе данных и
дальнейшей работы с ресурсами, занимаемых
данным подключением, следует использовать
команду close().
Обработка набора
записей ADO для построения формы ввода
данных: sub MakeDataEntryTable
После вызова
подпрограммы
ShowUserRecordset страница
ReadWriteDB.asp
размещает элемент формы HTML на странице
браузера, позволяющей пользователю
отправлять данные на сервер. Подпрограмма
AddData
осуществляет прием данных, отправленных из
HTML-формы на веб-странице. Форма HTML,
используемая для получения данных от
пользователя, должна соответствовать
обновляемой форме набора данных. В данной
ситуации информации, вводимой пользователем
для отправки на сервер, присваиваются те же
имена, что в полям в таблице базы данных, к
которой они относятся. Подпрограмма
MakeDataEntryTable
создает таблицу HTML, содержащую заголовки с
именами полей набора записей, являющиеся
частью набора записей, сгенерированного
переданным в подпрограмму SQL-выражением.
Эта подпрограмма использует для построения
таблицы HTML такой же механизм цикла, как и
подпрограмма
ShowUserRecordset. Обратитесь к
листингу 12.10 для изучения кода
подпрограммы
MakeDataEntryTable.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'sub MakeDataEntryTable
'Using the SQL command and the
Connection object
'instance passed in, prints a table with
the field
'names for the headings and inputs for
the fields.
'
'in
' sSQL =
SQL command for recordset
' oConnection =
ADO connection object
'out - nothing - writes to client
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sub MakeDataEntryTable(byval sSQL, byval
oConnection)
dim myRecordset
dim sResult
dim oField
'create the recordset
set myRecordset = Server.CreateObject("ADODB.Recordset")
myRecordset.Open sSQL, oConnection
'build a table for user to enter values
sResult = "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0
>" &_
vbCRLF
sResult = sResult & "<TR>"
'make the headings
for each oField in myRecordset.Fields
sResult = sResult &
"<TH>" & oField.Name & "</TH>"
next
'make a new row
sResult = sResult & "</TR>" & vbCRLF & "<TR>"
'make the user inputs
for each oField in myRecordset.Fields
sResult = sResult & _
"<TD> <input TYPE=""text"" NAME=""" & _
oField.Name & """ VALUE=""""></TD>"
next
sResult = sResult & "</TABLE>"
Response.Write(sResult)
'shut down recordset and connection objects
myRecordset.Close()
end sub
Листинг
12.10. Part of ReadWriteDB.asp -
MakeDataEntryTable Subroutine
Serializing a Recordset into an HTML
Table
Выполнение
ReadWriteDB.asp
приведет к построению в браузере страницы,
отображающей имеющиеся в таблице базы данных
значения, строку, таблицу с именами полей и
поля ввода во второй строке, а также кнопку
Add (Добавить). Нажатие на кнопку Add (Добавить)
без ввода данных во все текстовые поля
приведет к обновлению страницы. При вводе
данных во все четыре поля эти данные
запишутся в таблицу базы данных
tblEmployee.
На рисунке 12.12 изображена страница
ReadWriteDB.asp
с введенными в нее данными.
Рис. 12.12.
Методы
программирования: абстракция логики и
расширяемость. Подпрограммы
ShowUserRecordset
и MakeDataEntryTable
обеспечивают поддержку любого набора записей
или объекта подключения. Их можно
использовать в других приложениях, где
требуется реализация таких же действий без
изменения кода. При изменении формы таблицы
базы данных эти подпрограммы будут
функционировать без корректирования кода.
Тем не менее,
возможности данных подпрограмм довольно
ограничены при их использовании в других
приложениях, поскольку они содержат логику
отображения. Веб-приложения для своей работы
требуют наличия альтернативного
пользовательского интерфейса. При
абстрагировании логики представления от
подпрограмм последние стали бы намного
полезнее при работе в широком спектре
приложений. Код, который можно применить к
широкому ряду приложений, называется
расширяемым. Обобщение различных компонентов
логики значительно увеличивает уровень
расширяемости в коде, но, как правило,
отрицательно сказывается на
производительности и скорости разработки.
Работа с
XML
Одной из
технологий, применяемых для обобщения логики
отображения, является язык XML. XML – это не
разновидность кода, хотя многие программисты
говорят, что умеют программировать на XML.
XML на самом деле представляет собой
иерархический формат, используемый для
описания данных с помощью текста. Данные,
описываемые с помощью XML, имеют множество
преимуществ по сравнению с другими форматами
хранения данных. Текст XML распознается и
обрабатывается всеми операционными системами.
С другой стороны, XML понятен и человеку.
XML обрабатывается и конструируется с
помощью общего набора правил,
задокументированных для множества
потенциальных потребителей XML.
XML имеет и
свои недостатки: ему требуется гораздо
больший объем пространства для хранения
данных по сравнению с другими технологиями (формат
с разделителями-запятыми или текст
фиксированной ширины). XML требует много
ресурсов для обработки и упорядочивания
данных. Для иллюстрации преимуществ и
недостатков сравним файл XML с текстовым
файлом с разделителями-запятыми. Оба файла
являются текстовыми и используются в любой
операционной системе. Оба файла являются
результатом упорядочивания информации в
таблице базы данных в соответствующий формат
данных. Файл XML примерно в 3 – 5 раз больше,
чем версия того же набора данных в формате
текстового файла с разделителями-запятыми,
так как в последнем не используются элементы
описания для каждой строки и значения данных,
как в файле XML. Обработка файла XML
занимает больше времени в зависимости от
того, насколько его размер больше файла с
разделителями-запятыми.
Рассмотрим
ситуацию, когда XML-файл и файл с
разделителями-запятыми отправляются
сторонним потребителям, и в таблицу базы
данных добавляется еще один столбец. В файл
с разделителями-запятыми добавится еще один
столбец с любой стороны от текста или в его
середине, в зависимости от логики экспорта,
использованной для создания этого файла.
Файл XML также будет содержать
дополнительные данные, но, поскольку каждое
значение данных в нем определено явным
образом, то при использовании файла
потребителем не возникнет ошибки, пока
потребитель руководствуется установленными
правилами. А программное обеспечение,
обрабатывающее файл с разделителями-запятыми,
вызовет ошибку, поскольку формат файла не
совпадет с тем, что "ожидало" приложение.
Преобразование с помощью XSL
XML обобщает
логику отображения, разрешая существование
этой логики в другом файле. При помощи
программного обеспечения, комбинирующего XML
и логику отображения посредством
установленного набора инструкций, XML можно
преобразовать в другой тип документа,
например, в HTML. Известными наборами
инструкций являются Extensible Slylesheet
Language (XSL) (Расширяемый язык таблиц
стилей) и Extensible Stylesheet Language
Transformation (XSLT) (Преобразование
расширяемого языка таблиц стилей). С помощью
обобщения логики отображения программисты
разрабатывают веб-приложения для создания
документов XML, предназначенных для описания
данных или некоторого объекта.
Пользовательский интерфейс можно изменять по
мере необходимости, корректируя код только в
файлах XSL или XSLT.
В листинге
12.11 приведен пример простого
преобразования, реализованного в ASP.
<%@
Language=VBScript %>
<HTML>
<HEAD>
</HEAD>
<BODY>
<%
dim oXMLDoc
dim oXMLXSL
Set oXMLDoc = Server.CreateObject("Microsoft.XMLDOM")
Set oXMLXSL = Server.CreateObject("Microsoft.XMLDOM")
oXMLDoc.load(Server.MapPath("employees.xml"))
oXMLXSL.load(Server.MapPath("employeesDisplay.xsl"))
Response.Write( oXMLDoc.transformNode(oXMLXSL) )
%>
</BODY>
</HTML>
Листинг
12.11. XMLToHTML.asp - Simple XML to
HTML Transformation Performed in an ASP
Страница
XMLtoHTML.asp
(см. листинг 12.11) создает экземпляр класса
XMLDOM. Класс
XMLDOM
является частью библиотеки Microsoft MSXML,
используемой для преобразования XML и XSL в
HTML. MSXML содержит набор классов и других
программных решений, обеспечивающих XML-обработку,
проверку, конструирование и прочие полезные
функции XML. Функция загрузки класса
XMLDOM
вызывается указанием полного имени файла в
качестве аргумента функции. Загружаемый файл
расположен в корневом веб-каталоге, поэтому
для получения полного физического пути и
имени XML-файла вызвана функция
Server.MapPath.
Функция загрузки класса
XMLDOM
обрабатывает в качестве аргумента строку,
содержащую документ XML или полное имя файла.
В листинге
12.12 приведено содержимое загруженного
файла XML.
<?xml
version="1.0"?>
<Recordset Table = "MyMembership"
Command = "Select *
From tblEmployee">
<Row number = "3" phone = "444-4444"
first_name = "Susy"
last_name = "Lipschitz" />
<Row number = "4" phone = "444-555"
first_name = "Bertan"
last_name = "Scudder" />
<Row number = "6" phone = "444-4444 "
first_name = "Joe"
last_name = "Schmidlap" />
<Row number = "8" phone = "444-4444 "
first_name = "Tom"
last_name = "Cleasak" />
</Recordset>
Листинг
12.12. employees.xml - tblEmployee Data
Serialized into an XML Document
Этот документ
представляет собой простой XML-файл,
содержащий сведения о сотрудниках,
извлеченные из таблицы
tblEmployee (см.
листинг 12.10).
Действия,
аналогичные созданию экземпляра класса и
загрузке документа XML, выполнены по
отношению к таблице стилей XSL. XSL – это
документ XML, и так же, как XML,
воспринимается классом
XMLDOM. В
листинге 12.13 приведено содержимое файла
XSL, загруженного в данном примере.
<?xml
version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:template match="/">
<xsl:for-each select="Recordset">
<P><xsl:value-of select="@Table"/>
<br/><xsl:value-of select="@Command"/><br/>
</P>
<TABLE BORDER="1" CELLSPACING="0"
CELLPADDING="0">
<TR>
<TH>Number</TH>
<TH>Phone</TH>
<TH>First Name</TH>
<TH>Last Name</TH>
</TR>
<xsl:for-each select="Row">
<TR>
<TD><xsl:value-of
select="@number"/></TD>
<TD><xsl:value-of select="@phone"/></TD>
<TD><xsl:value-of select="@first_name"/></TD>
<TD><xsl:value-of select="@last_name"/></TD>
</TR>
</xsl:for-each>
</TABLE>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Листинг
12.13. employeesDisplay.xsl - XSL
Stylesheet to Make HTML from tblEmployee
XML Document
После
загрузки документов XSL и XML в свои
собственные экземпляры класса
XMLDOM из
экземпляра XMLDOM,
связанного с документом XML, вызывается
функция transformnode.
Экземпляр класса
XMLDOM, содержащий документ XSL,
используется в качестве аргумента при вызове
функции transformnode,
а результирующей строкой, возвращаемой
функцией
transformnode, является документ
HTML. На рисунке 12.13 представлен результат
преобразования документов XSL и XML,
отображенный в браузере.
Рис. 12.13. Отображение данных
браузером в результате преобразования
формата XML в HTML
HTML-код,
полученный из XML, приведен в листинге
12.12, а XSL, приведенный в листинге 12.13,
в преобразованном состоянии показан в
листинге 12.14.
<HTML>
<HEAD>
</HEAD>
<BODY>
<P>MyMembership
<br />Select * From tblEmployee<br />
</P>
<TABLE BORDER="1" CELLSPACING="0"
CELLPADDING="0">
<TR>
<TH>Number</TH>
<TH>Phone</TH>
<TH>First Name</TH>
<TH>Last Name</TH>
</TR>
<TR>
<TD>3</TD>
<TD>444-4444</TD>
<TD>Susy</TD>
<TD>Lipschitz</TD>
</TR>
<TR>
<TD>4</TD>
<TD>444-555</TD>
<TD>Bertan</TD>
<TD>Scudder</TD>
</TR>
<TR>
<TD>6</TD>
<TD>444-4444</TD>
<TD>Joe</TD>
<TD>Schmidlap</TD>
</TR>
<TR>
<TD>8</TD>
<TD>444-4444</TD>
<TD>Tom</TD>
<TD>Cleasak</TD>
</TR>
</TABLE>
</BODY>
</HTML>
Листинг
12.14. HTML Resulting from XSL
employeesDisplay.xsl and XML
employees.xml Document Transformation
|