Проблемы повторного
использования программного обеспечения и интегрирования различных
информационных систем возникли на заре развития IT
индустрии. Пройдя на пути решения этих задач от использования
библиотек функций до объектно-ориентированного программирования и
бинарных стандартов вызовов объектов, таких COM,
CORBA, IT индустрия
подошла вплотную к выработке стандартов в области механизмов
взаимодействия систем. На смену вопросу “Чей клей для склеивания
приложений лучше?” приходят вопросы “Где взять универсальный клей?” и
“Будет ли мой объект хорошо держаться универсальным клеем?”. Какие
механизмы и протоколы могут получить широкое распространение и будут
приняты в качестве стандартов? Основанные на RPC
(Remote Procedure Call), бинарные
протоколы, помимо того, что они несовместимы между собой, не могут
решить задачи взаимодействия в распределенных Web
приложениях, поскольку только HTTP
трафик гарантированно переносит информацию через
Firewalls. Необходим новый подход.
Концепция
Web Services призвана решить эту задачу
объединения, интеграции разнородных систем на основе открытых
стандартов. Основанная на SOAP и
XML, эта концепция предлагает путь
взаимодействия объектов, реализованных в различных бинарных стандартах,
через Internet. Web
Services являются поворотом от Internet
обозревателей к Internet распределенных
приложений.
SOAP
представляет собой протокол обмена XML
сообщениями между объектами для передачи информации о вызываемых
методах, параметрах и возвращаемых значениях. SOAP
основан на XML и формат его сообщений не
зависит от транспортного протокола передачи сообщений. Реализация
SOAP поверх HTTP
находится на рассмотрении W3C.
Уже сейчас ведутся работы по разработке реализаций поверх других
транспортных протоколов передачи сообщений, таких как
SMTP, MSMQ. Но для построения
распределенных приложений одного формата обмена не достаточно. Нужен
механизм описания предоставляемых объектом интерфейсов.
WSDL предназначен для решения этой задачи.
WSDL так же подан на рассмотрение в
W3C консорциум. Для
перечисления Web Services, раскрываемых на
данном Web сервере, используется простейший
протокол DISCO. Если провести аналогии с
C OM протоколом, то можно соотнести
RPC (COM) и
SOAP как протоколы вызовов объектов,
WSDL(COM) и
Type Library (SOAP)
как форматы описания типов объектов, Registry(COM)
и DISCO(SOAP) как
хранилище списка локально доступных объектов. . UDDI
решает задачу глобального каталога Web
Services.
На наших глазах концепция
Web Services выходит сегодня из стадии только
обсуждения и стандартизации в стадию реализации. Многие производители
ПО заявили о планах или уже выпускают инструментальные средства для
создания Web Services.
Microsoft .NET Framework и
Visual Studio.NET,
выпуск которых намечен на осень этого года, предоставляют разработчикам
мощный инструментарий для создания XML Web Services
и построения распределенных Web приложений.
Давайте рассмотрим
процесс создания достаточно простого распределенного приложения,
использующего Web Service. Приложение будет
состоять из уровня данных, реализованного в SQL
Server, уровня бизнес логики, реализованного как
Web Service и уровня пользовательского
интерфейса, который мы реализуем в виде Windows
приложение с GUI и в виде приложения с
тонким клиентом в браузере. Клиентские приложения будут реализовывать
просмотр и редактирование данных о продуктах из таблицы
Products базы данных
Northwind, входящей в поставку SQL Server
2000. C базой данных клиентские приложения
будут общаться через Web Service, по протоколу
HTTP и SOAP.
Рис.
Архитектура распределенного приложения в примере.
Итак, поскольку искомая
БД уже имеется в нашем распоряжении, начнем c
уровня бизнес логики, т.е. с Web Service.
Создание Web Service
Мы знаем, как, например,
в Visual Basic, создать COM
объект для повторного использования. (ссылка на статью) Попытаемся
ответить на вопрос, насколько отличается разработка
Web Service среде Visual Studio.NET
от создания ActiveX DLL в
Visual Basic 6.0.
Наш Web
Service будет раскрывать два метода:
GetProducts , для получения информации о продуктах и UpdateProducts
, для изменения информации в БД.
SOAP
не ограничен передачей только простых типов данных и позволяет
передавать в качестве параметров и возвращаемых значений структуры и
массивы. Естественно, как Вы могли и предположить, сложные типы данных
представляются в виде в формате XML в теле
SOAP сообщений.
Используем эту
возможность при построении нашего Web Service
и будем возвращать объект типа DataSet (ADO.NET)
. Передача его через SOAP возможна в силу
того, что он имеет интерфейс для представления своего состояния в
XML формате. Не рассказывая подробно об
ADO.NET, отмечу, что
через объект типа DataSet мы можем работать с
наборами данных, без постоянного соединения с источником данных.
Фактически DataSet представляет собой СУБД,
реализованную в памяти. Сформировав DataSet ,
передадим его на сторону клиента. После изменений набора данных
клиентское приложение может передать DataSet
обратно на уровень бизнес логики, где и произойдет синхронизация с
реальной базой данных. Начнем разработку:
1.
Запустите Visual Studio.NET
2.
через меню File|
New| Project
откройте диалоговое окно выбора типа нового проекта.
3.
Выберите Visual C#
Projects (выбор языка, в конце концов,
может быть делом вкуса) на панели Project Types
и ASP.NET
Web Service на панели
Templates
4.
Назовите проект NorthwindProductsWS и
укажите http://localhost
в качестве Web сервера.
5.
После нажмите на OK
и Visual Studio создаcт
новый Solution
с нашим проектом.
Добавим два объекта к
Web Service: SqlDataAdapter, после
соединения с БД посредством SqlConnection,
выполнит запрос к таблице Products и заполнит
данными объект DataSet .
SqlDataAdapter будет так же изменять БД на основе набора данных,
возвращенного от пользователя.
6.
Откройте Server Explorer,
выбрав пункт меню View
| Server Explorer
7.
Сделайте правый клик на Data Connections
и выберите Add Connection
из ниспадающего меню.
8.
В Data Link Properties
диалоговом окне заполните информацию для установления соединения
с Northwind базой данных
9.
нажмите OK
для установления соединения.
10.
В Server Explorer раскройте
ServerName.Northwind.dbo
и затем раскройте узел Tables.
11.
Отбуксируйте мышью таблицу Products
на панель дизайна. Пара SqlConnection
и SqlDataAdapter, обеспечивающая
соединение с источником данных, появится в нижней части
панели дизайна
1.
Через меню Data |
Generate DataSet вызовите
диалог, выберите New
и назовите dataset
ProductsDS1.
2.
Сохраните файлы через меню File
| Save All.
Теперь мы сделаем доступным
DataSet для
использования из Windows или
Web приложений по протоколу
SOAP, добавив методы к нашему WebService.
Web Service будем реализовывать в классе
Service1, сгенерированном при создании
проекта. При желании мы могли создать свой класс, наследовав его из
System.Web.Services.WebService.
1.
В Solution Explorer
двойным щелчком мыши откройте Service1
и откройте код через меню View
| Code.
2.
Добавьте метод для получения данных. Метод будет создавать
новый dataset типа
ProductsDS1 и заполнять его, используя
SqlDataAdapter. После этого метод возвратит
DataSet.
[WebMethod]
public ProductsDS1
GetProducts()
{
ProductsDS1
ds = new DataSet1();
sqlDataAdapter1.Fill(ds);
return ds;
}
3.
Добавьте метод для сохранения произведенных клиентским
приложением изменений обратно в базу данных. Метод
Update принимает
изменения в dataset.
Dataset возвращается клиентскому приложению, которое отразит
изменения в собственном экземпляре products1
dataset.
[WebMethod]
public ProductsDS1
UpdateProducts(ProductsDS1 ds)
{
if( ds !=
null)
{
sqlDataAdapter1.Update(ds);
return ds;
}
else
{
return
null;
}
}
4.
Сохраните все файлы и постройте проект - Build
| Build.
Итак, мы только что
создали объект уровня бизнес логики, методы которого доступны через
SOAP вызовы. От нас не потребовалось знания
XML и SOAP – С#
компилятор по атрибуту [WebMethod] знает, что
наш объект должен быть доступен по SOAP.
Посмотрим, в каком формате наш Web Service
возвращает объект DataSet. Для этого запустим
Internet Explorer и укажем
URL: http://localhost/NorthwindProductsWS/Service1.asmx.
ASP.NET на основе
описания класса объекта, реализующего Web Service,
сгенерирует страницу, с которой мы можем в интерактивном режиме вызывать
методы Web Service. Вызовем метод
GetProducts. Для этого по ссылке перейдем
на страницу тестирования метода и нажмем Invoke.
Рис.
Возвращаемые данные после вызова метода
GetProducts
Как мы видим XML
сообщение, в котором передается DataSet,
содержит и описание структуры данных и сами данные.
Переходим к созданию Windows
приложения с GUI. Процесс его создания
практически не будет отличаться от создания подобного приложения в
Visual Basic 6.0.
Создание клиентского
приложения с Windows GUI
1.
Вызовите меню File
|Add Project
и кликните на New Project .
2.
В диалоговом окне Add New Project
выберите Visual
C# Projects
на панели Project Types
и Windows Application
на панели Templates.
3.
Назовите проект ProductsWinClient.
Form1
автоматически добавится к проекту и появится в визуальном дизайнере
форм.
4.
Добавьте ссылку на наш Web Service:
a.
В Solution Explorer
кликните правой кнопкой мыши на
ProductsWinClient
проект, и выберите Add Web Reference
на ниспадающем меню.
b.
Кликните по ссылке Web References on
Local Web Server.
c.
Из появившегося списка ссылок выберите ссылку на
NorthwindProductsWS
d.
Нажмите Add Reference
Теперь мы можем создавать
экземпляры products1
dataset в клиентском приложении.
Добавление ссылки на WebService очень похоже
на добавление ссылки на библиотеку типов ActiveX
объекта в Visual Basic 6.0. Только
информацию о типах в первом случае Visual Studio
берет в формате WSDL, а во втором в формате
TypeLibrary. Попутно замечу, что
WSDL для нашего Web Service
ASP.NET генерирует
на лету, в чем можно убедиться, указав ссылку
http://localhost/NorthwindProductsWS/Service1.asmx?WSDL в
Internet Explorer.
Список
доступных WebServices Visual Studio получает
из файла DISCO на Web
сервере.
Осталось
создать интерфейс для работы с dataset.
1.
Отбуксируйте DataGrid
control с Windows Forms
панели из Toolbox
на форму.
2.
Добавьте на форму Button
control, установив для нее свойство Name
в LoadData
и свойство Text
в Загрузить.
3.
Добавьте на форму еще одну Button
control, установив для нее свойство Name
в SaveData
и свойство Text
в Сохранить.
4.
Отбуксируйте DataSet
объект с Data
панели из Toolbox
на форму. Откроется дилог Choose a DataSet.
Выберите Typed dataset
и укажите
"ProductsWinClient.ServerName.ProductsDS1" из списка
Name . Visual Studio.NET
создаст DataSet
объект на основе определения класса
productsDS1.
5.
Выберите DataSet
control и установите свойство Name
в ProductData.
6.
Выберите DataGrid
control и укажите ProductData
из списка в свойстве DataSource.
Выберите products из списка в свойстве
DataMember .
Названия колонок DataGrid
будут установлены в названия колонок из таблицы
Products.
Добавим код для кнопок
1.
Двойным щелчком мыши по кнопке LoadData
откройте пустой обработчик события Click.
Для обращения к Web Service сначала создадим
экземпляр объекта, а затем вызовем его методы. Возвращенный
dataset из метода
GetProducts соединяется с ProductData
dataset.
private
void Load_Click(object
sender, System.EventArgs e)
{
ProductsWinClient.localhost.Service1 ws =
new
ProductsWinClient.localhost.Service1();
this.dataSet11.Merge(ws.GetProducts());
}
2.
Реализуйте обработчик события Click
для кнопки Save.
Если есть изменения в
dataset, новый dataset типа
productsDS1 создается для сохранения
только что измененных данных. Потом он передается в метод
UpdateProducts
нашего Web Service. После возврата из метода
он содержит принятые изменения и ProductData
dataset принимает эти изменения.
private
void Save_Click(object
sender, System.EventArgs e)
{
if(
dataSet11.HasChanges())
{
ProductsWinClient.localhost.Service1 ws =
new
ProductsWinClient.localhost.Service1();
ProductsWinClient.localhost.DataSet1 diffDS =
new
ProductsWinClient.localhost.DataSet1();
diffDS.Merge(dataSet11.GetChanges());
ws.UpdateProducts(diffDS);
dataSet11.Merge(diffDS);
}
}
3. Выберите ProductsWinClient
в Solution Explorer, и по
нажатию на правую кнопки мыши, через соответствующий пункт ниспадающего
меню, укажите это проект как StartUp Project.
4. Запустите
приложение, нажав на F5.
Протестируйте наше клиентское приложение, нажимая на кнопки и внося
изменения в данные.
Создание клиентского приложения с Web
интерфейсом
Построим теперь приложение с
Web интерфейсом и используем тот же самый
объект уровня бизнес логики.
1.
Для создания Web приложения укажите
ASP.NET Web Application
в диалоге создания нового проекта.
2.
Назовите ProductsWebClient.
Страница с Web Form
- WebForm1.aspx –
будет добавлена к проекту и загружена в дизайнер.
3.
Добавьте ссылку на Web Service,
точно так же, как сделали это для проекта с Windows
приложением
4. Отбуксируйте
DataSet control
с панели Data
из Toolbox
на форму. В открывшемся диалоге Choose a
DataSet выберите
TypedDataSet и
укажите "ProductsWebClient.ServerName.Products1"
в списке Name
. DataSet
control будет добавлена на форму.
5.
Для DataSet
control установите совйство Name
в ProductData.
6.
Отбуксируйте DataGrid
control с панели Web Forms из
Toolbox на
форму.
7.
В окне Properties
для DataGrid
control установите DataSource
свойство в ProductData
и DataMember свойство в products.
Эти установки должны предлагаться в ниспадающих списках. Названия
колонок DataGrid
будут установлены в названия колонок из таблицы
Products.
8. Для поддержки
редактирования на месте в DataGrid
control, Вы должны добавить Edit,
Update, Cancel
колонку, которая будет содержать кнопку редактирования. Когда
пользователь нажмет кнопку редактирования содержимое строки будет
отображено в TextBox (отдельно для каждой
колонки), и кнопка редактирования будет заменена на
Update и
Cancel кнопки.
Чтобы добавить эту кнопку:
a.
Кликните на Property Builder
ссылку внизу окна Properties
и выберите Columns
панель в диалоговом окне.
b.
Раскройте узел Button Column
в панели Available Columns.
c.
Выберите Edit, Update, Cancel
и нажмите кнопку Add
.
d.
Нажмите OK.
Добавим код для кнопок
1.
По нажатию правой клавиши мыши выберите из ниспадающего меню
View Code.
Добавим код к событию Page_Load.
В этом фрагменте мы создадим экземпляр нашего
Web Service, заполним ProductData
dataset, и свяжем его с DataGrid.
Каждый раз, когда страница отправляется клиенту в ответ на запроc,
таблица будет содержать свежую копию данных из базы данных.
private
void Page_Load(object
sender, System.EventArgs e)
{
// Put user code to
initialize the page here
ProductsWebClient.localhost.Service1 ws =
new
ProductsWebClient.localhost.Service1();
this.dataSet11.Merge(ws.GetProducts());
if(!Page.IsPostBack)
{
DataGrid1.DataBind();
}
}
2.
Когда пользователь нажимает кнопку Edit,
генерируется событие EditCommand
объекта DataGrid. Используем это
событие для изменения индекса EditItemIndex
в DataGrid. Строка с указанным
индексом отобразится в виде набора TextBox.
Создаем обработчик
событий для EditCommand. :
В oкне
свойств для DataGrid нажмите на кнопку
Events и отобразите список событий DataGrid.
Добавьте код к событию EditCommand
.
private
void DataGrid1_EditCommand(object
source,
System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
DataGrid1.EditItemIndex = e.Item.ItemIndex;
DataGrid1.DataBind();
}
3.
Создайте обработчик ошибок для события
CancelCommand
private
void DataGrid1_CancelCommand(object
source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
DataGrid1.EditItemIndex = -1;
DataGrid1.DataBind();
}
Когда
пользователь нажимает на кнопку Cancel
, генерируется событие CancelCommand
объекта DataGrid. Установим в
коде для этого события EditItemIndex
в -1 так что текущая строка будет отображаться снова в виде
набора TextBox.
4.
Когда пользователь нажимает на Update
, генерируется событие UpdateCommand
объекта DataGrid
. В этом событии мы должны получить ProductData
dataset с изменениями из DataGrid
и провести эти изменения обратно в базу данных через обращение к
Web Service.
private
void DataGrid1_UpdateCommand(object
source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
for(
int i = 0; i<
DataGrid1.Columns.Count-1; i++)
{
TextBox tb =
(TextBox)e.Item.Cells[i].Controls[0];
DataRow row =
dataSet11.products[e.Item.DataSetIndex];
row[DataGrid1.Columns[i].HeaderText] = tb.Text;
}
if(dataSet11.HasChanges())
{
ProductsWebClient.localhost.Service1 ws =
new
ProductsWebClient.localhost.Service1();
ProductsWebClient.localhost.DataSet1 ds =
new
ProductsWebClient.localhost.DataSet1();
ds.Merge(dataSet11.GetChanges());
ws.UpdateProducts(ds);
dataSet11.Merge(ds);
}
DataGrid1.EditItemIndex = -1;
DataGrid1.DataBind();
}
5.
Выберите ProductsWebClient
в Solution Explorer,
и по нажатию на правую клавишу мыши выберите его как
Set as StartUp Project.
6.
Запустите приложение, нажав на F5.
Отметим, что создание
Web приложений c
использованием ASP.NET
происходит аналогично созданию Windows
приложений с GUI. Мы отдельно работали с
формой нашей страницы и отдельно писали код для обработки ошибок. Ничто
не напоминало “кашу” ASP страниц, с
перемешенными HTML тегами и кусками скриптов.
Помимо
Visual Studio.NET
Microsoft предлагает и другие инструменты для создания и
использования Web Services.
SOAP Toolkit можно использовать вместе с
Visual Studio 6.0. SOAP Toolkit
предоставляет объекты для генерирования proxy,которые
берут на себя уровень взаимодействия по SOAP и
вы обращаетесь к Web Services как к обычным
COM объектам. SOAP Toolkit
содержит два набора интерфейсов – высокоуровневый и
низкоуровневый, для возможности влиять на формирующиеся
SOAP сообщения. Дополнительно к
SOAP Toolkit можно использовать
Web Service Proxy Wizard, который добавляется
как Add-On к среде
Visual C++ 6.0. Web
Service Proxy Wizard генерирует класс на основе
Web Services и библиотеку типов для этого
класса. Это позволяет использовать раннее связывание в проектах в
Visual Basic 6.0 при обращении к
Web Service. Сгенерированный класс работает
через SOAP Toolkit на низкоуровневом
интерфейсе. Кроме того, для Internet Explorer
доступен HTC компонент, который позволяет
работать с Web Services напрямую из
DHTML на стороне браузера. Все эти
дополнительные средства доступны для загрузки на
http://msdn.microsoft.com
в разделе Downloads.
Как мы только что
убедились, создание и иcпользование
Web Services при разработке в среде
Visual Studio.NET
мало чем отличается от работы с COM объектами
и дает нам возможность построения распределенных в приложений, не
ограниченных рамками корпоративной сети. Значит ли это что
Web Services нужно использовать при любом
удаленном взаимодействии объектов? Выскажу свою точку зрения. Являясь
действительно простым протоколом, SOAP имеет и
свои естественные ограничения. Он не обеспечивает поддержку
распределенных транзакций, накладывает дополнительные расходы на
паковку/распаковку данных в XML формат.
SOAP и Web Service
полностью не вытеснят удаленные взаимодействия объектов через бинарные
протоколы, а скорее дополнят их. SOAP и
Web Service найдут свое применение прежде
всего
§
при построении внешних интерфейсов во внутренние системы
компаний,
§
при необходимости поддерживать различные типы клиентских
приложений в многоуровневых системах
§
при построении B2B
портальных решений
§
для построения распределенных систем с поддержкой
необходимости взаимодействия модулей через Internet
§
при построении публичных, ориентированных на использование
частными клиентами услуг и приложений.
Это не значит, что
Web Services будут использоваться только в
приложениях для частных пользователей. Приведу в качестве примера пару
конкретных сценариев вероятного использования Web
Services в корпоративной информационной системе:
1. Удаленное взаимодействие модулей системы
(классический “удаленный склад”)
2. Портал дистрибутора. Предложить Вашим партнерам
возможность работы не только через Web
интерфейс но и возможность прямой интеграции их учетных систем через
Internet по протоколу SOAP
с Вашей системой. Использование при этом стандартных
XML сообщений, например
CommerceML, который поддерживается в тиражируемом программном
обеспечении ведущих российских производителей ПО, позволит многим Вашим
контрагентам осуществить такую интеграцию без особых усилий.
Web
Services находятся в начале пути своего становления и широкого
распространения. При их построении нужно еще решать много вопросов,
связанных с аутентификацией, предоставлением гарантированного уровня
обслуживания, проработкой новых бизнес моделей распространения
коммерческого программного обеспечения и т.п.. В последующих статьях на
страницах … мы затронем различные аспекты создания
Web Services – от рассмотрения протоколов и техники
программирования отдельных особенностей до рассмотрения реальных
реализаций примеров работающих Web Services.
Но уже сейчас очевидно, что концепция Web Services
выводит IT индустрию новый уровень развития
построения распределенных приложений на основе открытых стандартов.
Стандартизация основополагающих протоколов Web
Services строить на этой концепции стратегию развития
информационных систем.