<% 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.-->
Что же такое Active X? (Небольшое «лирическое» отступление)
А зачем, собственно, применять Active X-технологию в ASP?
Создание и подготовка базы данных
Формируем главную страницу (index.asp)
Форма загрузки (UploadForm.asp)
(Обработка формы загрузки с помощью ActiveX-компонента Upload2DBS.asp)
Загрузка файлов с помощью ASP и VBScript
А теперь давайте попробуем сами разработать ActiveX-компонент…
…с помощью Microsoft Visual Basic 6.0
… с помощью Microsoft Visual C++ 6.0
Еще несколько слов в защиту C++
Введение
В первой статье серии «<% 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"> Today is: <!- Отобразим дату -> <% D = Date() D = FormatDateTime(D,2) Response.Write D %> </font></b></td> <td> </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"> </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 %> …