ASP на блюдечке. Часть 2 ActiveX-компоненты и ASP

ASP на блюдечке. Часть 2 ActiveX-компоненты и ASP

If you build it, they will come. If you make it dynamic
(using ASP, ActiveX and this article) they'll come back more often.

Рубен Садоян

Введение

В первой статье серии «ASP на блюдечке» («ASP на блюдечке. Часть 1. Построение интерфейса к базе данных», КомпьютерПресс 9 за 2000 год) мы ознакомились с ASP, а также с принципами построения с его помощью простейшего интерфейса к базе данных (газетный сайт со встроенными возможностями его пополнения новыми статьями, снабжаемыми фотографиями непосредственно с самого сайта и без программирования). Теперь я предложу читателям обогатить этот интерфейс возможностями загрузки (upload) HTML-статьи и иллюстрации к ней непосредственно с сайта (то есть с HTML-формы), ведения автоматической статистики посещений, организации показа баннеров, а также методами использования и азами разработки Активных Серверных Компонентов (Active Server Components) для ASP. Статья будет весьма полезна начинающим Web-программистам, профессионалам же достаточно беглого взгляда, чтобы понять принципы и вникнуть в детали работы активных серверных страниц — ASP.

Итак…

Что же такое Active X? (Небольшое «лирическое» отступление)

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

Итак, что же такое COM (Component Object Model) и ActiveX? Чтобы ответить на этот вопрос, зададимся сначала другим: каким образом одна часть программного обеспечения должна получать доступ к сервисам, предоставляемым другой частью? Сегодня ответ на этот вопрос зависит от того, что представляют собой эти части. Например, приложения, скомпонованные с библиотекой, могут пользоваться ее сервисами, вызывая функции из этой библиотеки. Приложение может также использовать сервисы другого — являющегося совершенно отдельным процессом. В данном случае два локальных процесса взаимодействуют посредством некоего механизма связи, который обычно требует определения протокола между этими приложениями (набор сообщений, позволяющий одному приложению выдавать запросы, а другому соответствующим образом отвечать на них). Еще пример: приложение, использующее сервисы операционной системы. Здесь приложение обычно выполняет системные вызовы, обрабатываемые операционной системой. Наконец, приложению могут понадобиться сервисы, предоставляемые программным обеспечением, выполняемым на другой машине, доступ к которой осуществляется по сети. Получить доступ к таким сервисам можно множеством способов, таких как обмен сообщениями с удаленным приложением или вызовы удаленных процедур.

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

Каждый такой объект поддерживает один или несколько интерфейсов, состоящих из методов. Метод — это функция или процедура, которая выполняет некоторое действие и может быть вызвана программным обеспечением, использующим данный объект (клиентом объекта). Методы, составляющие каждый из интерфейсов, обычно определенным образом взаимосвязаны. Клиенты могут получить доступ к сервисам объекта COM только через вызовы методов интерфейсов объекта — у них нет непосредственного доступа к данным объекта.

А зачем, собственно, применять Active X-технологию в ASP?

Применение встраиваемых в ASP ActiveX-компонентов значительно облегчает задачу создания сайтов. Посудите сами: ведь создание громоздких функций, выполняющих сложные вычисления, да и простых подпрограмм гораздо удобнее с помощью известных всем языков программирования, таких как Visual Basic, Delphi или C++, а сгенерированный код (.dll или .ocx) будет работать во много раз быстрее, ведь скомпилированный код модуля выполняется почти мгновенно, в то время как препроцессор ASP формирует HTML-страницу для каждого клиента гораздо дольше. Реализация этих функций средствами самого ASP во многих случаях будет нетривиальна, а в некоторых — попросту невозможна. Кроме того, многие полезные компоненты доступны со стороны так называемых третьих фирм (third-party components), которые зачастую распространяются бесплатно (или почти бесплатно).

Итак, я надеюсь, что эта статья поможет вам научиться применять «чужие» компоненты (third-party components) и разрабатывать свои.

С чего начать?

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

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

Что для этого понадобится?

Для реализации вышеизложенной задачи необходим персональный компьютер с Microsoft Windows NT или Windows 2000 (можно и Workstation или Server), установленный IIS (Internet Information Server), какой-нибудь HTML-редактор (советую использовать Macromedia Dreamweaver), Microsoft Access (версии 95, 97 или 2000) и самый обычный текстовый редактор.

Создание и подготовка базы данных

Для начала нашего первого эксперимента создадим базу данных статей, а для этого:

  • запустим приложение Microsoft Access;
  • любым из известных способов создадим новую базу данных (назовем ее «Articles»);
  • в созданной базе данных создадим таблицу с именем, например, «Articles»;
  • пользуясь инструментом «Конструктор», определим поля нашей таблицы и типы принимаемых ими значений:

  • заполним таблицу несколькими статьями в соответствии с созданными полями;

  • сохраним базу данных в файле «ArticlesDB.mdb»

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

  • запустим программу-конфигуратор источников данных (Data Sources ODBC) — Start->Settings->Control Panel->Administrative Tools->Data Sources ODBC;
  • перейдем во вкладку «System DSN» и создадим новый источник данных, нажав на «Add…»;
  • в появившемся списке драйверов выберем драйвер баз данных Microsoft Access — «Microsoft Access Driver (*.mdb)» и нажмем на «Finish»;
  • в строке «Data Source Name» зададим имя нашей базы данных, например «Articles» (это то имя, по которому мы в дальнейшем будем обращаться к ней);
  • нажмем на «Select…», выберем подготовленный нами файл «ArticlesDB.mdb» и нажмем «OK».

Появляется строка в списке источников данных в вашей системе:

Применение ActiveX в ASP

Мировая компьютерная сеть «кишит» и платными, и бесплатными ActiveX-компонентами. Последний параграф настоящей статьи — попытка перечислить наиболее популярные. Для загрузки файла с HTML-формы советую использовать компонент AspUpload 2.0 Copyright (c) 1998-2000  Persist Software, Inc. (http://www.persits.com/). Компонент платный, но временную одномесячную версию вы сможете найти на нашем CD-ROM.

Формируем главную страницу (index.asp)

…

<!- Определяем таблицу ->

<table BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH="710">

<tr>

<td WIDTH="232"><img SRC="Images\Banner.jpg"  height=60 width=232></td>

<td WIDTH="10"></td>

<td WIDTH="468"></td>

</tr>

<tr>

<td BGCOLOR="#000000"><b><font color="#FFFFFF">&nbsp;Today  is:

<!- Отобразим дату ->

<%

D = Date()

D = FormatDateTime(D,2)

Response.Write D

%>

</font></b></td>

<td>&nbsp;</td>

<td></td>

</tr>

 

<!- Линки на основные страницы ->

<tr>

<td BGCOLOR="#FFCC99" valign = top>

<a href="http://localhost/List.asp" class="antiLine">

<b> Show Articles List</b></a><br>

<a href="http://localhost/Search/SearchForm.asp" class="antiLine">

<b>Search for an article</b></a><br>

<a href="http://localhost/Upload/UploadForm.asp" class="antiLine">

<b>Upload an article</b></a><br>

<a href="http://localhost/Signin.asp" class="antiLine">

<b>Signing In</b></a><br>

</td>

<td></td>

<td>

<%

‘ Подключимся к таблице Articles базы данных Articles и откроем ее

Set db = Server.CreateObject("ADODB.Connection")

db.Open "Articles"

‘ Сформируем SQL запрос и выполним его

sSQL = "SELECT * FROM Articles Where IsTopNew = '1' Order by ID DESC"

Set rs = db.Execute(sSQL)

Display = 0

‘ В цикле будем считывать значения полей и добавлять их в таблицу

Do While NOT Rs.EOF

MainImage = rs.Fields("IFile1").value Имя файла с иллюстрацией к  текущей
 статье

ShouldDisplay = rs.Fields("IsDImage").value

‘Переменная, определяющая, должна ли иллюстрация отображаться

If NOT rs.EOF and Display = 0 and MainImage <> "No" and
  ShouldDisplay = "1" Then

Display = 1 ‘ Если да, то сгенерировать соответствующий тэг с
 именем иллюстрации

Response.Write "<img SRC=" & "Articles\" &
  MainImage & " height=300 width=468>"

End If

Rs.MoveNext

Loop

%>

</td>

</tr>

<%

Set rs = db.Execute(sSQL)

Cnt = 0

Do While NOT Rs.EOF

%>



<tr>

<td BGCOLOR="#FFCC99">&nbsp;</td>

<td></td>

 

<td>

<%

If rs.Fields("Article").value <> "No Text" Then ‘Если  поле текста
 статьи не равно "No Text"

Link = "<a href= http://localhost/ArtTempl.asp?id=" &
 rs.Fields("ID").value & ">" &
  rs.Fields("Title").value & "</a>"

Else ‘В противном случае сгенерировать линк на HTML-файл со статьей

Link = "<a href= http://localhost/Articles/" &
 rs.Fields("TextFile").value & ">" &
  rs.Fields("Title").value & "</a>"

End If

 

Response.Write Link & "<br>"

‘ Добавляем автора статьи

Response.Write "<i>By " & rs.Fields("Author").value  &
 "</i><br>"

 

‘ Добавляем аннотацию к статье

ANN = rs.Fields("Annotation").value

If ANN <> "NA" Then

Response.Write ANN

End If

%>

<hr NOSHADE WIDTH="100%">

</td>

</tr>

<%

Rs.MoveNext

Cnt = Cnt + 1

Loop

 

db.Close

Set db = Nothing

%>

</table>

…

 

Следует обратить особое внимание на формирование переменной «Link». В первом случае, когда значение поля «Article» не равно «No Text», ссылка на статью формируется из файла шаблона ArtTempl.asp, которому идентификатор текущей статьи передается в качестве параметра

Link ="<a
href= http://localhost/ArtTempl.asp?id="&rs.Fields("ID").value&
">"&rs.Fields("Title").value &"</a>"

(дальнейшая обработка в теле файла шаблона подробно обсуждалась в первой части настоящей статьи).

В противном случае ссылка на статью формируется из имени файла (которое содержится в переменной TextFile) с ее HTML-версией, который уже подгружен на сервер и располагается в каталоге «Articles».

Link ="<a
 href= http://localhost/Articles/" &rs.Fields("TextFile").value
  &">"& rs.Fields("Title").value &"</a>"

Загружаем файл с HTML-формы

Форма загрузки (UploadForm.asp)

Для начала необходимо создать соответствующую форму. Предполагается, что читатель знаком с азами построения форм (для этих целей советую воспользоваться Macromedia Dreamweaverом), тем не менее я обращу внимание на пару тэгов формы загрузки файлов (полная версия формы загрузки прилагается к данной статье).

Хочется обратить особое внимание на обработку «радиокнопки», определяющей тип статьи («горячая» — «не горячая») и флажок показа иллюстрации на главной странице. Если читатель знаком с первой статьей, то он, вероятно, вспомнит, что в целях обучения вся обработка формы (проверка корректности ввода полей и первоначальная обработка введенных значений) велась на ASP. Приведенный ниже пример иллюстрирует то, как это на самом деле следует делать с помощью какого-либо языка описания сценариев (в нашем случае JavaScript).

В нашем случае мы будем определять состояние флажка показа иллюстрации с помощью небольшого скрипта на JavaScript и «спрятанного» (hidden) поля. Последнее будет принимать значение, соответствующее состоянию флажка.

< script >

function preprocess ()

{

message = 2;

if (mainform.DI.checked) message = 1;

else message = 2;

mainform.details.value = message;

}

</script>

Как видно, значение поля «details» будет равно 1, если флажок поля «DI» был установлен, и 2 — в противном случае. Вызов самого скрипта удобнее всего выполнять по событию «onsubmit», которое обрабатывается по нажатию на кнопку «Submit», и вплоть до передачи управления скрипту-реакции. Таким образом, на этапе ввода можно осуществлять инициализацию внутренних полей и переменных формы, причем непосредственно на стороне клиента (как известно, языки описания скриптов JavaScript и VBScript именно для этого и предназначены). В нашем случае фрагмент формы будет выглядеть следующим образом:

…

<form name="mainform" method="post" enctype="multipart/form-data"

action="http://localhost/Upload/Upload2DBS.asp" onsubmit="preprocess();">

…

<input type="radio" name="IsTopNewSelector" value="0"  checked> <b>
 Ordinary type Article

<input type="radio" name="IsTopNewSelector" value="1">  Top New type
Article</b>

…

<b>Display image on Home page

<input type="checkbox" name="DI" value="0">

<input type="hidden" name="details">

<i>(only for Top News type articles) </i></b>

…

</form>

…

Соответственно радиокнопка «IsTopNewSelector» будет возвращать значение «0» для обычной и значение «1» для «горячей» статьи.

Обработка формы загрузки с помощью ActiveX-компонента Upload2DBS.asp

Работать с ActiveX-компонентами в ASP достаточно просто. Например, загрузка файлов при помощи компонента «ASPUpload» производится всего двумя строчками кода:

<%

Set Upload = Server.CreateObject("Persits.Upload.1") ‘Создаем
 переменную  — указатель на интерфейс Upload

 Count = Upload.Save ("c:\InetPub\wwwroot\Articles") ‘ Вызываем функцию
  Save этого интерфейса

 ‘ И присваиваем переменной Count число подгруженных файлов

%>

Фактически после отработки этих двух строк все файлы, которые были указаны в полях формы, загружаются на сервер — в данном случае в каталог "c:\InetPub\wwwroot\Articles".

Далее необходимо произвести обработку остальных полей формы и добавить запись в базу данных:

…

<%

I = 0

FileI = "No"

Set FI = Upload.Files("IFile1") ‘ Определяем указатель на погруженный
  файл

 If Not FI Is Nothing Then ‘ И если он не пуст

 FileI = FI.Path ‘ То читаем полный путь к подгруженному файлу

 strPosition = Instr(25,FileI,"\") ‘ Вырезаем из полного пути собственно
  имя файла

intStringLen=strPosition-1

strLeft = Left(FileI,intStringLen)

strRight = Right(FileI,(Len(FileI)-Len(strLeft)-1))

FileI = strRight ‘ И присваиваем его переменной FileI

End If

…

Аналогичные действия должны быть выполнены и с файлом HTML (если таковой был указан)

Set TF = Upload.Files("TextFile")

If Not TF Is Nothing Then

FileT = TF.Path

strPosition = Instr(25,FileT,"\")

intStringLen=strPosition-1

strLeft = Left(FileT,intStringLen)

strRight = Right(FileT,(Len(FileT)-Len(strLeft)-1))

FileT = strRight ‘ И присваиваем его переменной FileТ

End If

ErrA = 0 ‘ Заводим четыре флажка для обработки ошибок ввода полей

ErrT = 0

ErrP = 0

ErrC = 0

‘ Получаем значение флажка показа иллюстрации

DI = Upload.Form("DETAILS")

If DI = 1 Then

IsDisplayImage = "1"

End If

If DI = 2 Then

IsDisplayImage = "0"

End If

‘ Получаем значение поля автора статьи

AUT = Upload.Form("Author")

If AUT = "" Then ErrA = 1 End If

AUT = FormatStr(AUT)

‘ Получаем значение поля заголовка статьи

TIT = Upload.Form("Title")

If TIT = "" Then ErrT = 1 End If

TIT = FormatStr(TIT)

‘ Получаем значение поля текста самой статьи

ART = Upload.Form("Article")

If ART = "" Then

ART = "No Text" ‘ Если оно пусто, присваиваем переменной константу
  "No Text"

If File1 = "No" Then

ErrC = 1

End If

End If

‘ Форматируем текст самой статьи для его последующего показа в формате
 HTML  ART = FormatStr(ART)

 ‘ Получаем значение селектора рубрик SBJ = Upload.Form("Subject")

IsTopNew = Upload.Form("IsTopNewSelector")

ANN = Upload.Form("Annotation")

ANN = FormatStr(ANN)

If ANN = "" Then

ANN = "NA"

End If

‘ Получаем значение поля пароля доступа к базе данных
' Password = Upload.Form("Password")

If Password = DBP Then

If ErrA = 0 and ErrT = 0 Then

 

‘ Открываем базу данных и записываем в нее значения

Set db = Server.CreateObject("ADODB.Connection")

db.Open "DSN=Articles;UID=sa;PWD=;"

sSQL = "insert into

Articles(Author,Title,Article,Subject,TextFile,IFile1,Published,IsTopNew,
Annotation,IsDImage)values('" & AUT &

 "', '" & TIT & "','" & ART & "','" & SBJ & "',
 '" & FileT & "','" & FileI & "','" & TIM &"',
 '" & IsTopNew &"','" &

ANN & "','" & IsDisplayImage &"')"

Set rs = db.Execute(sSQL)

db.Close

Set db = Nothing

End If

Else

ErrP = 1

End If

%>

…