С помощью ASP программист может быстро создавать веб-приложения на сервере Windows, использующем IIS третьей версии (или выше). ASP вышла в свет в то время, когда между собой соперничали технологии программирования Common Gateway Interface (CGI) и Perl, используемые многими программистами для разработки веб-приложений. ASP прекрасно вписывается в стратегию Microsoft ActiveX, поскольку обеспечивает функциональность, инкапсулированную в компоненты COM, и позволяет разработчикам реализовывать n-звенные решения с помощью ASP и COM.
Примечание. Листинги кода в этой лекции доступны на веб-сайте автора http://mapobject.com/iis6/.
Файлы ASP представляют собой сценарии, интерпретируемые по мере
поступления запросов. Расширение ASP.DLL связано в IIS с
файлами, имеющими расширения .asp или . (см. рис. 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 представляют собой простые текстовые файлы, поэтому для их создания и правки используется любой текстовый редактор. Microsoft Visual Interdev шестой версии представляет собой утилиту для редактирования и создания файлов ASP. Разработчики, как правило, используют другие программы – TextPad, NotePad (Блокнот) и даже Dreamweaver. Для редактирования файлов ASP рекомендуется применять также Visual Studio .NET.
В данной лекции для редактирования и создания файлов ASP используется Visual Interdev. Для открытия нового файла ASP с помощью Interdev выполните следующие действия.
(рис 12.2) Создание нового ASP-файла в Visual InterdevVBScript по умолчанию является языком страниц 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 или ., файлы ASP – расширения .asp
или .. Службы IIS различают типы файлов по их расширениям и
определяют соответствующее расширение MyAspFile.asp переименовать в MyAspFile.aspx, то при запросе MyAspFile он будет обработан технологией
.NET, а не с помощью расширения ASP ASP.DLL )..
Более подробно работа с Visual Studio .NET и ASP.NET показана в лекции 2 курса "Программирование в IIS".
Примечание. Несмотря на возможность совместной работы ASP и ASP.NET на
одном веб-сервере, они не могут использовать общий сеанс, поскольку
каждый тип файла обрабатывается своим программным обеспечением. Файлы
ASP.NET обрабатываются библиотекой aspnet_isapi.dll, которая, в свою
очередь, использует для выполнения кода технологию .NET.
Недостатком Visual Interdev является то, что эта программа требует большого количества ресурсов, поэтому при выполнении простых задач слишком много времени тратится на ее открытие. Если разработчику нужно быстро отредактировать файл, то для этого прекрасно подойдет программа Notepad (Блокнот) или Textpad. Visual Interdev является лицензированным программным продуктом, а это делает его самым дорогим среди аналогичных программ.
Если вы только что установили сервер или на нем раньше никогда не применялась технология ASP, то IIS не будет поддерживать ASP. Для установки поддержки ASP выполните следующие несложные действия.
(рис 12.4) Установка поддержки ASP в мастере компонентов WindowsВ Windows Server 2003 и IIS 6 появилась новая функция, ограничивающая всякую программную поддержку серверной части по умолчанию и требующая обязательного наличия поддержки программирования серверной части.
Запрос на обработку файла при отсутствии установленного расширения
(рис 12.5) Включение расширения веб-службНа веб-сайте или в виртуальном каталоге необходимо также установить разрешения на выполнение сценариев (script). По умолчанию параметр Execute Permissions (Разрешения на выполнение) в окне Properties (Свойства) сайта IIS или виртуального каталога не включен. Для включения параметра выполните следующие действия.
(рис 12.6) Настройка разрешений на выполнение для виртуального каталогаС помощью объекта Response код ASP может выполнять запись текста на
клиенте – любого содержимого, включая код, выполняющийся на клиенте.
IIS различает код, выполняющийся на сервере, и содержимое, отправляемое
клиенту с помощью расширения
На рисунке 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, использующего response.write
ASP содержит следующие объекты, обеспечивающих потребности разработчика в реализации решения, отвечающего на событие веб-запроса.
Как и все объекты ASP, класс объекта Response всегда доступен коду ASP
во время веб-запроса. Этот объект обеспечивает потребность разработчика
в записи данных на компьютер-клиент во время выполнения веб-запроса.
Функция Write объекта Response возвращает клиенту содержимое
переданного ей аргумента. Объект Response также позволяет разработчику
контролировать запись данных в HTTP-запрос.
Объект Application используется, в основном, в файле global. для
фиксирования событий приложения ASP. Объектом Application фиксируются
следующие события.
Объект Application также используется для хранения переменных, не
меняющих свое состояние на протяжении всей работы веб-сайта. Объект Application остается активным с момента первого запроса веб-приложения
до момента отключения веб-сервера, поэтому он используется для хранения
данных, необходимых для всех запросов на страницы и всех веб-сеансов.
Объект 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>
При первом запросе пользователем ASP-кода (см. листинг 12.1) ему будет
предложено ввести свое имя. Если пользователь введет произвольный текст
в поле ввода с именем UserName и нажмет на кнопку отправки данных, то
это значение будет передано на сервер. Запрос попадет в тот же ASP-код,
с помощью которого создана страница, отображаемая пользователю.
ASP-страница называется askname.asp – это видно из атрибута ACTION
элемента FORM. При выполнении запроса askname.asp с веб-сервера объект Request используется для считывания значения в поле ввода с именем UserName:
Request("UserName")
Объект Request используется для запроса значения из строки запроса,
формы HTTP или элемента cookie посредством описанного метода присвоения
имени переменной. Объект Request предоставляет разработчику три набора
значений.
Все наборы поддерживают свойства 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 приведена подпрограмма subWriteCollection(c,CollectionName), считывающая аргумент набора и
выводящая в браузере, выполняющем запрос, имена и значения всех
элементов набора. Номера набора должны начинаться с единицы, а не с
нуля, как в других наборах. Подпрограмма WriteCollection вызывается
трижды из раздела BODY раздела HTML. При каждом вызове в подпрограмму
передается набор объекта Request. При выполнении файла ASP ShowRequestValues.asp (см. листинг 12.2) на экран выводятся
демонстрационные значения элементов cookie и строк запросов (см. рис.
12.9).
(рис 12.9) Вывод наборов запросаДва элемента cookies на компьютере-клиенте вывели результат запроса
файла ShowRequestValues.asp в следующие строки браузера:
#1 TheServer = Name=birdhouseNumber=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 соответственно.
Браузеры периодически выполняют кэширование веб-страницы или ее части.
Время сервера было записано в браузер (см. листинг 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" %>
Этот же результат можно получить более простым способом, добавив на
страницу строку Response.Expires=-1.
Элементы 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 показан код 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 представляет собой готовое средство управления
состоянием с помощью элементов 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 представляет собой код 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, что позволяет использовать его в качестве механизма
Session для демонстрации
аналогии хранения и получения данных с помощью сеанса и элемента
cookie. Файл ReadWriteSession.asp также устанавливает новое значение Session.Timeout, равное 1 минуте.
(рис 12.11) Сеанс по умолчанию, обновленный посредством нового свойства
и значений Session.Timeout
Объект Session имеет некоторые ограничения, с которыми необходимо
ознакомиться, прежде чем реализовывать Session. Сеанс не повторяется и не является общим
между серверами, работающими в так называемой веб-ферме.
Данные сеанса хранятся непосредственно на несущем сервере,
инициировавшем сеанс. При первом запросе пользователем ASP-страницы с
помощью сеанса ASP на хост клиента записывается сеансовый элемент
cookie. Сеансовый cookie содержит единственное значение, выступающее в
роли ключа. При запросе другой ASP-страницы библиотека ASP.DLL получает
сеансовый элемент cookie и просматривает данные, которые будут
присвоены объекту Sesion, с помощью ключа, полученного из сеансового
cookie. Если страница ASP обслуживается другим веб-сервером, входящим в
состав веб-фермы, то данные сеанса веб-сервера, на котором создан
элемент cookie, на этом хосте отсутствуют, и сеанс не будет загружен.
При использовании объекта ASP Session в его первоначальном виде можно
задействовать только один сервер. Решение этой проблемы заключается в
создании и использовании сеансового сервера, Session. ASP.NET предлагает более простое решение,
представляющее собой внутреннюю часть этой технологии; о нем мы
расскажем в лекции 2 курса Программирование в "IIS".
ASP часто используется для получения данных из хранилища информации, применения к ним некоторой бизнес-логики и отображения информации в браузере. Все эти задачи можно выполнить с помощью ASP, однако многие веб-программисты используют для этой цели другие программные библиотеки. ASP не содержит внутренней библиотеки для считывания источников данных, тем не менее, объект Server поддерживает функцию создания экземпляра объекта COM. Экземпляром объекта является любой объект COM с интерфейсом, который можно считать с помощью VBScript. Распространенный объект COM или набор объектов для считывания данных из источников называется Active Data Objects (ADO).
Целью разработки технологии ADO является предоставление разработчику универсального решения относительно доступа к данным для всех источников информации. В идеальном случае ADO выступает в роли абстракции между кодом бизнес-логики и источником данных любого вида. Изменяя набор параметров, указывающих на расположение источника данных, программа продолжает считывать и записывать данные в источник без корректирования кода. В настоящее время ADO обеспечивает такой тип абстракции между источниками данных с аналогичной структурой данных. Например, код ADO, используемый для считывания и записи данных в базу данных SQL Server, позволяет производить те же самые действия с информацией в базе данных Oracle без изменения кода.
Наследование технологий доступа к данным.
Microsoft выпустила также такие библиотеки доступа к данным, как Data
Access Objects (
Использование 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.BOF 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>
Объект подключения ADO. Первым объектом, создаваемым в коде листинга
12.6, является объект подключения ADO. Библиотеке ADO присваивается имя ADODB, а в качестве имени класса используется "Connection".
Таким образом, команда создания объекта выглядит следующим образом:
Set myConn = Server.CreateObject("ADODB.Connection")
Переменная myConn указывает на экземпляр класса ADO Connection. Класс Connection осуществляет хранение и передачу данных доступа к источнику
данных. В листинге 12.6 строка Object Linking and
База данных Microsoft Access.
Тем не менее, Microsoft Access имеет множество ограничений при
управлении большими наборами данных. Microsoft Access не обеспечивает
функциональных возможностей SQL Server и Oracle. Эта программа
представляет собой популярную утилиту чтения и записи файлов, поскольку
ресурс, из которого запрашиваются данные, предоставляется
приложением-потребителем. В ASP ресурс данных для запроса
предоставляется IIS. Тем не менее, прямо противоположным случаем
является база данных уровня предприятия, при работе с которой источник
данных для запроса ограничивается узлом. Разрешения на доступ к базе
данных Microsoft Access устанавливаются настройкой файловых разрешений.
В примерах, приводимых в данной лекции, учетной записи службы IIS с
именем IUSER_<имя компьютера> (где имя компьютера – это имя узла)
нужно предоставить разрешения на чтение и запись в файл базы данных
Microsoft Access .. Файл Microsoft Access имеет расширение . и
определяется в строке подключения OLE-DB.
Объект набора записей ADO. В рассматриваемом процессе участвует еще
один объект ADO с именем recordset – объект набора записей. С его
помощью программист осуществляет доступ к информации в наборе данных,
их чтение и запись в источник. Набор записей открывается с помощью
команды SQL и экземпляра объекта подключения MyConn. После вызова
функции Open объекта набора записей этот набор можно считать и записать
в браузер. Однако предварительно его нужно проверить на наличие в нем
записей. Набор является пустым, если оба условия – 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>
Файл ReadWriteDB содержит еще три подпрограммы, которые исключены из
листинга 12.7 для сокращения его объема. Листинг 12.7 показывает
главную точку входа ASP-кода ReadWriteDB, в которой расширение ASP.DLL начинает выполнять код серверной части. Дополнительными
подпрограммами файла ReadWriteDB.asp, исключенными из листинга 12.7,
являются следующие:
Connection подпрограмма выводит содержимое набора записей в
браузере;Request на предмет отправки
данных и вставляет переданные пользователем данные в таблицу базы
данных с именем tblEmployee.После блока комментариев "main
("главная точка входа в 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
В подпрограмме 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. Разработчики называют такой подход
программированием "вручную", а значения называются магическими значениями или литералами. Как правило, программирование
вручную реализуется для рационального и надежного выполнения, однако
лучше его избегать. Литералы, зависимые от конкретной реализации
приложения, нужно заменить и установить как параметры конфигурации
приложения, которое можно откорректировать без редактирования кода.
После записи отправленной в базу данных информации 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
Методы 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().
После вызова подпрограммы 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
Выполнение ReadWriteDB.asp приведет к построению в браузере страницы,
отображающей имеющиеся в таблице базы данных значения, строку, таблицу
с именами полей и поля ввода во второй строке, а также кнопку Add
(Добавить). Нажатие на кнопку Add (Добавить) без ввода данных во все
текстовые поля приведет к обновлению страницы. При вводе данных во все
четыре поля эти данные запишутся в таблицу базы данных tblEmployee. На
рисунке 12.12 изображена страница ReadWriteDB.asp с введенными в нее
данными.
(рис 12.12) Страница ReadWriteDB, отображенная в браузере перед
обновлением
Методы программирования: абстракция логики и расширяемость.
Подпрограммы ShowUserRecordset и MakeDataEntryTable обеспечивают
поддержку любого набора записей или объекта подключения. Их можно
использовать в других приложениях, где требуется реализация таких же
действий без изменения кода. При изменении формы таблицы базы данных
эти подпрограммы будут функционировать без корректирования кода.
Тем не менее, возможности данных подпрограмм довольно ограничены при их использовании в других приложениях, поскольку они содержат логику отображения. Веб-приложения для своей работы требуют наличия альтернативного пользовательского интерфейса. При абстрагировании логики представления от подпрограмм последние стали бы намного полезнее при работе в широком спектре приложений. Код, который можно применить к широкому ряду приложений, называется расширяемым. Обобщение различных компонентов логики значительно увеличивает уровень расширяемости в коде, но, как правило, отрицательно сказывается на производительности и скорости разработки.
Одной из технологий, применяемых для обобщения логики отображения, является язык XML. XML – это не разновидность кода, хотя многие программисты говорят, что умеют программировать на XML. XML на самом деле представляет собой иерархический формат, используемый для описания данных с помощью текста. Данные, описываемые с помощью XML, имеют множество преимуществ по сравнению с другими форматами хранения данных. Текст XML распознается и обрабатывается всеми операционными системами. С другой стороны, XML понятен и человеку. XML обрабатывается и конструируется с помощью общего набора правил, задокументированных для множества потенциальных потребителей XML.
XML имеет и свои недостатки: ему требуется гораздо больший объем
пространства для хранения данных по сравнению с другими технологиями
(формат с разделителями-запятыми или текст фиксированной ширины). XML
требует много ресурсов для обработки и
Рассмотрим ситуацию, когда XML-файл и файл с разделителями-запятыми отправляются сторонним потребителям, и в таблицу базы данных добавляется еще один столбец. В файл с разделителями-запятыми добавится еще один столбец с любой стороны от текста или в его середине, в зависимости от логики экспорта, использованной для создания этого файла. Файл XML также будет содержать дополнительные данные, но, поскольку каждое значение данных в нем определено явным образом, то при использовании файла потребителем не возникнет ошибки, пока потребитель руководствуется установленными правилами. А программное обеспечение, обрабатывающее файл с разделителями-запятыми, вызовет ошибку, поскольку формат файла не совпадет с тем, что "ожидало" приложение.
XML обобщает логику отображения, разрешая существование этой логики в
другом файле. При помощи программного обеспечения, комбинирующего XML и
логику отображения посредством установленного набора инструкций, XML
можно преобразовать в другой тип документа, например, в HTML.
Известными наборами инструкций являются Extensible Slylesheet Language
(XSL) (Расширяемый
В листинге 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>
Страница 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>
Этот документ представляет собой простой 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>
После загрузки документов XSL и XML в свои собственные экземпляры
класса XMLDOM из экземпляра XMLDOM, связанного с документом XML,
вызывается функция transformnode. Экземпляр класса XMLDOM, содержащий
документ XSL, используется в качестве аргумента при вызове функции transformnode, а результирующей строкой, возвращаемой функцией transformnode, является документ HTML. На рисунке 12.13 представлен
результат преобразования документов XSL и XML, отображенный в браузере.
(рис 12.13) Отображение данных браузером в результате преобразования формата XML в HTMLHTML-код, полученный из 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>
С помощью ASP программист может быстро создавать веб-приложения на сервере Windows, использующем IIS третьей версии (или выше). ASP вышла в свет в то время, когда между собой соперничали технологии программирования Common Gateway Interface (CGI) и Perl, используемые многими программистами для разработки веб-приложений. ASP прекрасно вписывается в стратегию Microsoft ActiveX, поскольку обеспечивает функциональность, инкапсулированную в компоненты COM, и позволяет разработчикам реализовывать n-звенные решения с помощью ASP и COM.
Примечание. Листинги кода в этой лекции доступны на веб-сайте автора http://mapobject.com/iis6/.
Файлы ASP представляют собой сценарии, интерпретируемые по мере
поступления запросов. Расширение ASP.DLL связано в IIS с
файлами, имеющими расширения .asp или . (см. рис. 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 представляют собой простые текстовые файлы, поэтому для их создания и правки используется любой текстовый редактор. Microsoft Visual Interdev шестой версии представляет собой утилиту для редактирования и создания файлов ASP. Разработчики, как правило, используют другие программы – TextPad, NotePad (Блокнот) и даже Dreamweaver. Для редактирования файлов ASP рекомендуется применять также Visual Studio .NET.
В данной лекции для редактирования и создания файлов ASP используется Visual Interdev. Для открытия нового файла ASP с помощью Interdev выполните следующие действия.
(рис 12.2) Создание нового ASP-файла в Visual InterdevVBScript по умолчанию является языком страниц 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 или ., файлы ASP – расширения .asp
или .. Службы IIS различают типы файлов по их расширениям и
определяют соответствующее расширение MyAspFile.asp переименовать в MyAspFile.aspx, то при запросе MyAspFile он будет обработан технологией
.NET, а не с помощью расширения ASP ASP.DLL )..
Более подробно работа с Visual Studio .NET и ASP.NET показана в лекции 2 курса "Программирование в IIS".
Примечание. Несмотря на возможность совместной работы ASP и ASP.NET на
одном веб-сервере, они не могут использовать общий сеанс, поскольку
каждый тип файла обрабатывается своим программным обеспечением. Файлы
ASP.NET обрабатываются библиотекой aspnet_isapi.dll, которая, в свою
очередь, использует для выполнения кода технологию .NET.
Недостатком Visual Interdev является то, что эта программа требует большого количества ресурсов, поэтому при выполнении простых задач слишком много времени тратится на ее открытие. Если разработчику нужно быстро отредактировать файл, то для этого прекрасно подойдет программа Notepad (Блокнот) или Textpad. Visual Interdev является лицензированным программным продуктом, а это делает его самым дорогим среди аналогичных программ.
Если вы только что установили сервер или на нем раньше никогда не применялась технология ASP, то IIS не будет поддерживать ASP. Для установки поддержки ASP выполните следующие несложные действия.
(рис 12.4) Установка поддержки ASP в мастере компонентов WindowsВ Windows Server 2003 и IIS 6 появилась новая функция, ограничивающая всякую программную поддержку серверной части по умолчанию и требующая обязательного наличия поддержки программирования серверной части.
Запрос на обработку файла при отсутствии установленного расширения
(рис 12.5) Включение расширения веб-службНа веб-сайте или в виртуальном каталоге необходимо также установить разрешения на выполнение сценариев (script). По умолчанию параметр Execute Permissions (Разрешения на выполнение) в окне Properties (Свойства) сайта IIS или виртуального каталога не включен. Для включения параметра выполните следующие действия.
(рис 12.6) Настройка разрешений на выполнение для виртуального каталогаС помощью объекта Response код ASP может выполнять запись текста на
клиенте – любого содержимого, включая код, выполняющийся на клиенте.
IIS различает код, выполняющийся на сервере, и содержимое, отправляемое
клиенту с помощью расширения
На рисунке 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, использующего response.write
ASP содержит следующие объекты, обеспечивающих потребности разработчика в реализации решения, отвечающего на событие веб-запроса.
Как и все объекты ASP, класс объекта Response всегда доступен коду ASP
во время веб-запроса. Этот объект обеспечивает потребность разработчика
в записи данных на компьютер-клиент во время выполнения веб-запроса.
Функция Write объекта Response возвращает клиенту содержимое
переданного ей аргумента. Объект Response также позволяет разработчику
контролировать запись данных в HTTP-запрос.
Объект Application используется, в основном, в файле global. для
фиксирования событий приложения ASP. Объектом Application фиксируются
следующие события.
Объект Application также используется для хранения переменных, не
меняющих свое состояние на протяжении всей работы веб-сайта. Объект Application остается активным с момента первого запроса веб-приложения
до момента отключения веб-сервера, поэтому он используется для хранения
данных, необходимых для всех запросов на страницы и всех веб-сеансов.
Объект 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>
При первом запросе пользователем ASP-кода (см. листинг 12.1) ему будет
предложено ввести свое имя. Если пользователь введет произвольный текст
в поле ввода с именем UserName и нажмет на кнопку отправки данных, то
это значение будет передано на сервер. Запрос попадет в тот же ASP-код,
с помощью которого создана страница, отображаемая пользователю.
ASP-страница называется askname.asp – это видно из атрибута ACTION
элемента FORM. При выполнении запроса askname.asp с веб-сервера объект Request используется для считывания значения в поле ввода с именем UserName:
Request("UserName")
Объект Request используется для запроса значения из строки запроса,
формы HTTP или элемента cookie посредством описанного метода присвоения
имени переменной. Объект Request предоставляет разработчику три набора
значений.
Все наборы поддерживают свойства 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 приведена подпрограмма subWriteCollection(c,CollectionName), считывающая аргумент набора и
выводящая в браузере, выполняющем запрос, имена и значения всех
элементов набора. Номера набора должны начинаться с единицы, а не с
нуля, как в других наборах. Подпрограмма WriteCollection вызывается
трижды из раздела BODY раздела HTML. При каждом вызове в подпрограмму
передается набор объекта Request. При выполнении файла ASP ShowRequestValues.asp (см. листинг 12.2) на экран выводятся
демонстрационные значения элементов cookie и строк запросов (см. рис.
12.9).
(рис 12.9) Вывод наборов запросаДва элемента cookies на компьютере-клиенте вывели результат запроса
файла ShowRequestValues.asp в следующие строки браузера:
#1 TheServer = Name=birdhouseNumber=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 соответственно.
Браузеры периодически выполняют кэширование веб-страницы или ее части.
Время сервера было записано в браузер (см. листинг 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" %>
Этот же результат можно получить более простым способом, добавив на
страницу строку Response.Expires=-1.
Элементы 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 показан код 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 представляет собой готовое средство управления
состоянием с помощью элементов 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 представляет собой код 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, что позволяет использовать его в качестве механизма
Session для демонстрации
аналогии хранения и получения данных с помощью сеанса и элемента
cookie. Файл ReadWriteSession.asp также устанавливает новое значение Session.Timeout, равное 1 минуте.
(рис 12.11) Сеанс по умолчанию, обновленный посредством нового свойства
и значений Session.Timeout
Объект Session имеет некоторые ограничения, с которыми необходимо
ознакомиться, прежде чем реализовывать Session. Сеанс не повторяется и не является общим
между серверами, работающими в так называемой веб-ферме.
Данные сеанса хранятся непосредственно на несущем сервере,
инициировавшем сеанс. При первом запросе пользователем ASP-страницы с
помощью сеанса ASP на хост клиента записывается сеансовый элемент
cookie. Сеансовый cookie содержит единственное значение, выступающее в
роли ключа. При запросе другой ASP-страницы библиотека ASP.DLL получает
сеансовый элемент cookie и просматривает данные, которые будут
присвоены объекту Sesion, с помощью ключа, полученного из сеансового
cookie. Если страница ASP обслуживается другим веб-сервером, входящим в
состав веб-фермы, то данные сеанса веб-сервера, на котором создан
элемент cookie, на этом хосте отсутствуют, и сеанс не будет загружен.
При использовании объекта ASP Session в его первоначальном виде можно
задействовать только один сервер. Решение этой проблемы заключается в
создании и использовании сеансового сервера, Session. ASP.NET предлагает более простое решение,
представляющее собой внутреннюю часть этой технологии; о нем мы
расскажем в лекции 2 курса Программирование в "IIS".
ASP часто используется для получения данных из хранилища информации, применения к ним некоторой бизнес-логики и отображения информации в браузере. Все эти задачи можно выполнить с помощью ASP, однако многие веб-программисты используют для этой цели другие программные библиотеки. ASP не содержит внутренней библиотеки для считывания источников данных, тем не менее, объект Server поддерживает функцию создания экземпляра объекта COM. Экземпляром объекта является любой объект COM с интерфейсом, который можно считать с помощью VBScript. Распространенный объект COM или набор объектов для считывания данных из источников называется Active Data Objects (ADO).
Целью разработки технологии ADO является предоставление разработчику универсального решения относительно доступа к данным для всех источников информации. В идеальном случае ADO выступает в роли абстракции между кодом бизнес-логики и источником данных любого вида. Изменяя набор параметров, указывающих на расположение источника данных, программа продолжает считывать и записывать данные в источник без корректирования кода. В настоящее время ADO обеспечивает такой тип абстракции между источниками данных с аналогичной структурой данных. Например, код ADO, используемый для считывания и записи данных в базу данных SQL Server, позволяет производить те же самые действия с информацией в базе данных Oracle без изменения кода.
Наследование технологий доступа к данным.
Microsoft выпустила также такие библиотеки доступа к данным, как Data
Access Objects (
Использование 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.BOF 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>
Объект подключения ADO. Первым объектом, создаваемым в коде листинга
12.6, является объект подключения ADO. Библиотеке ADO присваивается имя ADODB, а в качестве имени класса используется "Connection".
Таким образом, команда создания объекта выглядит следующим образом:
Set myConn = Server.CreateObject("ADODB.Connection")
Переменная myConn указывает на экземпляр класса ADO Connection. Класс Connection осуществляет хранение и передачу данных доступа к источнику
данных. В листинге 12.6 строка Object Linking and
База данных Microsoft Access.
Тем не менее, Microsoft Access имеет множество ограничений при
управлении большими наборами данных. Microsoft Access не обеспечивает
функциональных возможностей SQL Server и Oracle. Эта программа
представляет собой популярную утилиту чтения и записи файлов, поскольку
ресурс, из которого запрашиваются данные, предоставляется
приложением-потребителем. В ASP ресурс данных для запроса
предоставляется IIS. Тем не менее, прямо противоположным случаем
является база данных уровня предприятия, при работе с которой источник
данных для запроса ограничивается узлом. Разрешения на доступ к базе
данных Microsoft Access устанавливаются настройкой файловых разрешений.
В примерах, приводимых в данной лекции, учетной записи службы IIS с
именем IUSER_<имя компьютера> (где имя компьютера – это имя узла)
нужно предоставить разрешения на чтение и запись в файл базы данных
Microsoft Access .. Файл Microsoft Access имеет расширение . и
определяется в строке подключения OLE-DB.
Объект набора записей ADO. В рассматриваемом процессе участвует еще
один объект ADO с именем recordset – объект набора записей. С его
помощью программист осуществляет доступ к информации в наборе данных,
их чтение и запись в источник. Набор записей открывается с помощью
команды SQL и экземпляра объекта подключения MyConn. После вызова
функции Open объекта набора записей этот набор можно считать и записать
в браузер. Однако предварительно его нужно проверить на наличие в нем
записей. Набор является пустым, если оба условия – 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>
Файл ReadWriteDB содержит еще три подпрограммы, которые исключены из
листинга 12.7 для сокращения его объема. Листинг 12.7 показывает
главную точку входа ASP-кода ReadWriteDB, в которой расширение ASP.DLL начинает выполнять код серверной части. Дополнительными
подпрограммами файла ReadWriteDB.asp, исключенными из листинга 12.7,
являются следующие:
Connection подпрограмма выводит содержимое набора записей в
браузере;Request на предмет отправки
данных и вставляет переданные пользователем данные в таблицу базы
данных с именем tblEmployee.После блока комментариев "main
("главная точка входа в 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
В подпрограмме 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. Разработчики называют такой подход
программированием "вручную", а значения называются магическими значениями или литералами. Как правило, программирование
вручную реализуется для рационального и надежного выполнения, однако
лучше его избегать. Литералы, зависимые от конкретной реализации
приложения, нужно заменить и установить как параметры конфигурации
приложения, которое можно откорректировать без редактирования кода.
После записи отправленной в базу данных информации 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
Методы 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().
После вызова подпрограммы 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
Выполнение ReadWriteDB.asp приведет к построению в браузере страницы,
отображающей имеющиеся в таблице базы данных значения, строку, таблицу
с именами полей и поля ввода во второй строке, а также кнопку Add
(Добавить). Нажатие на кнопку Add (Добавить) без ввода данных во все
текстовые поля приведет к обновлению страницы. При вводе данных во все
четыре поля эти данные запишутся в таблицу базы данных tblEmployee. На
рисунке 12.12 изображена страница ReadWriteDB.asp с введенными в нее
данными.
(рис 12.12) Страница ReadWriteDB, отображенная в браузере перед
обновлением
Методы программирования: абстракция логики и расширяемость.
Подпрограммы ShowUserRecordset и MakeDataEntryTable обеспечивают
поддержку любого набора записей или объекта подключения. Их можно
использовать в других приложениях, где требуется реализация таких же
действий без изменения кода. При изменении формы таблицы базы данных
эти подпрограммы будут функционировать без корректирования кода.
Тем не менее, возможности данных подпрограмм довольно ограничены при их использовании в других приложениях, поскольку они содержат логику отображения. Веб-приложения для своей работы требуют наличия альтернативного пользовательского интерфейса. При абстрагировании логики представления от подпрограмм последние стали бы намного полезнее при работе в широком спектре приложений. Код, который можно применить к широкому ряду приложений, называется расширяемым. Обобщение различных компонентов логики значительно увеличивает уровень расширяемости в коде, но, как правило, отрицательно сказывается на производительности и скорости разработки.
Одной из технологий, применяемых для обобщения логики отображения, является язык XML. XML – это не разновидность кода, хотя многие программисты говорят, что умеют программировать на XML. XML на самом деле представляет собой иерархический формат, используемый для описания данных с помощью текста. Данные, описываемые с помощью XML, имеют множество преимуществ по сравнению с другими форматами хранения данных. Текст XML распознается и обрабатывается всеми операционными системами. С другой стороны, XML понятен и человеку. XML обрабатывается и конструируется с помощью общего набора правил, задокументированных для множества потенциальных потребителей XML.
XML имеет и свои недостатки: ему требуется гораздо больший объем
пространства для хранения данных по сравнению с другими технологиями
(формат с разделителями-запятыми или текст фиксированной ширины). XML
требует много ресурсов для обработки и
Рассмотрим ситуацию, когда XML-файл и файл с разделителями-запятыми отправляются сторонним потребителям, и в таблицу базы данных добавляется еще один столбец. В файл с разделителями-запятыми добавится еще один столбец с любой стороны от текста или в его середине, в зависимости от логики экспорта, использованной для создания этого файла. Файл XML также будет содержать дополнительные данные, но, поскольку каждое значение данных в нем определено явным образом, то при использовании файла потребителем не возникнет ошибки, пока потребитель руководствуется установленными правилами. А программное обеспечение, обрабатывающее файл с разделителями-запятыми, вызовет ошибку, поскольку формат файла не совпадет с тем, что "ожидало" приложение.
XML обобщает логику отображения, разрешая существование этой логики в
другом файле. При помощи программного обеспечения, комбинирующего XML и
логику отображения посредством установленного набора инструкций, XML
можно преобразовать в другой тип документа, например, в HTML.
Известными наборами инструкций являются Extensible Slylesheet Language
(XSL) (Расширяемый
В листинге 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>
Страница 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>
Этот документ представляет собой простой 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>
После загрузки документов XSL и XML в свои собственные экземпляры
класса XMLDOM из экземпляра XMLDOM, связанного с документом XML,
вызывается функция transformnode. Экземпляр класса XMLDOM, содержащий
документ XSL, используется в качестве аргумента при вызове функции transformnode, а результирующей строкой, возвращаемой функцией transformnode, является документ HTML. На рисунке 12.13 представлен
результат преобразования документов XSL и XML, отображенный в браузере.
(рис 12.13) Отображение данных браузером в результате преобразования формата XML в HTMLHTML-код, полученный из 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>
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.