Простая
web-служба
Как упоминалось
в главе 9, непосредственное
извлечение информации из web-страниц
— процесс медленный (из-за
необходимости анализировать всю
страницу) и ненадежный, поскольку
структура страницы может
измениться. Удобным средством
получения таких данных с web-сайта
является web-служба (Web service).
Иначе говоря,
сайт предоставляет свою
функциональность средствами, с
которыми можно работать в
программах (с точки зрения
программиста VB сайт, на котором
работает web-служба, напоминает
компонент, который предоставляет
свою функциональность программе).
Выражаясь
точнее, web-служба представляет
собой функциональную возможность
сервера, с которой клиент работает
при помощи HTML, XML и стандартных
протоколов Web.
В .NET создание web-служб,
используемых в клиентских
программах, становится делом почти
элементарным. В сущности, для этого
достаточно определить класс .NET и
пометить его члены, доступные через
web-службу, атрибутом <WebMethod( )>.
Рассмотрим простой пример —
допустим, мы создаем web-службу для
возвращения информации о погоде.
Для
простоты в нашем примере
возвращаемые данные жестко
кодируются в функции GetWeather.
Создайте новый
проект web-службы, для чего следует
выбрать значок ASP .NET Web Service в
диалоговом окне New Project. Результат
показан на рис. 12.3.
Рис. 12.3. Проект
web-службы в IDE
Дважды щелкните
на дизайнере и обратите внимание на
автоматически сгенерированный код:
Public Class
Servicel
Inherits System.Web.Services.WebService
Класс System. Web.
Services. WebServi се является базовым для
всех web-служб .NET. Благодаря
наследованию в вашем распоряжении
оказываются все возможности этого
класса, в том числе и свойство Context
для получения запроса HTTP,
использованного для обращения к
странице через Web.
Включите
следующий фрагмент перед командой
End Class:
<WebMethod()>Public Function GetWeather(ByVal City As String)
As String Select
Case City
' Получить информацию о погоде в Сиэттле
Case "Seattle"
Return "The
current temperature is 64 degrees. " & _
"and raining of course."
Case Else
Return "Can't find data for " & City & "."
End Select
End Function
При нажатии
клавиши F5 VS .NET IDE автоматически
генерирует web-страницу наподобие
показанной на рис. 12.4. На этой
странице приводится общая
информация о web-службе.
Рис. 12.4. Автоматически
сгенерированная страница с
описанием web-службы
При
создании web-службы VS.NET IDE
автоматически генерирует XML-файл с
описанием службы, написанный на
языке WSDL (Web Service Language Description).
Программисты COM могут
рассматривать его как аналог
библиотеки типов. Редактирование
сгенерированного файла .vsdisco
позволяет изменить информацию о web-службе,
содержащуюся в файле WSDL. В
частности, рис. 12.4 был получен на
основании кода WSDL.
Использование
web-службы на стороне клиента
Если щелкнуть
на ссылке GetWeather на рис. 12.4, в
броузере загружается страница,
показанная на рис. 12.5. На странице
приведен код, который может
использоваться для обращения к web-службе.
В разделе «SOAP» описывается доступ к
службе через протокол SOAP,
основанный на XML. Этот протокол
отличается наибольшей гибкостью,
но простым его не назовешь. В
простейшем варианте обращения к web-службе
используется запрос HTTP GET. Прототип
выглядит следующим образом:
/WebServicel/Servicel.asmx/
GetWeather?city=string НTTР/1.1
Host:Local Host
Рис. 12.5. Простейший
вариант использования web-службы
Введите в
текстовом поле строку Seattle и
нажмите кнопку Invoke. Примерный вид
страницы показан на рис. 12.6.
Рис. 12.6. Результаты
обращения к web-службе
Результат
представлен в формате XML, что
позволяет легко проанализировать
данные в программе. Также обратите
внимание на то, что в автоматически
сгенерированном коде показано, как
обращаться к web-службе за пределами
IDE. Для этого необходимо лишь
сгенерировать правильный запрос HTTP
GET или SOAP. Ниже приведен пример
построения запроса GET в консольном
приложении, использующем для
отправки запроса GET классы WebRequest и
WebResponse пространства имен System.Net:
1 Imports System.Net
2 Imports System.I0
3 Module Module1
4 Sub Main()
5 Dim myResponse As
WebResponse
6 Try
7 Dim
myWebServiceRequest As WebRequest
8
myWebServiceRequest - WebRequest.Create _
9 ("align="left">asmx/GetWeather?dty=SeattIe")
10 myResponse = _
11
myWebServiceRequest.GetResponse()
12 Dim theAnswer As
String
13 Dim aStream As New StreamReader
(myResponse.GetResponseStream)
14 theAnswer =
aStream.ReadToEnd
15 MsgBox(theAnswer)
16 Catch e As
Exception
17 Console.WriteLine(e.Message)
18 Finally
19 myResponse. Close()
20 End Try
21 End Sub
22 End Module
Ключевая роль в
этом листинге принадлежит строке 8 (продолжающейся
в строке 9), в которой серверу
передается запрос GET. Как было
показано в главе 9, результат
представляет собой поток данных,
используемый для построения StreamReader
(строка 13). Строка 14 читает в
строковую переменную весь текст
потока. Строка 19 закрывает объект
запроса HTTP и освобождает все связанные
с ним ресурсы. Кстати, переменная
myResponse была объявлена в строке 5
именно потому, что при объявлении
ее в блоке Try (строки 6-15) переменная
оказалась бы недоступной для
секции Fi nal ly. Результат выполнения
программы показан на рис. 12.7.
Рис. 12.7. Результат
обращения к web-службе с
использованием запроса GET
С запросами SOAP
дело обстоит несколько сложнее.
Вряд ли кому-нибудь захочется
генерировать их вручную. Вместо
этого можно воспользоваться
командой Project > Add Web Reference или
утилитой командной строки wsdl.exe,
входящей в поставку .NET Framework. Оба
варианта приводят к одному
результату — генерируется
вспомогательный класс-посредник,
который используется в программе.
Пожалуй,
решение с утилитой командной
строки отличается большей
гибкостью. Ниже показано, как
выглядела командная строка в нашем
случае. Хотя приведенный пример
разбит на две строки, его следует
ввести в одной строке:
"С:\Program Fi1es\Microsoft.NET\FrameworkSDK\Bin\wsdl"/language:VB"
align="left">При запуске с
ключом /language: VB утилита создает файл
с кодом вспомогательного класса
Servicel.vb, по умолчанию находящийся в
одном каталоге с wsdl.exe (выходной
каталог задается ключом out).
Основной код сгенерированного
класса выглядит так (ключевые
строки выделены жирным шрифтом):
Option Strict Off
Option Explicit On
Imports System
Imports System.Diagnostics
Imports System.Web.Services
Imports System.Web.Servi
ces.Protocols
Imports System.Xml.Serialization
'This source code was auto-generated by wsdl,Version=l.0.2914.16.
<System.Web.Servi ces.WebServi ceBi ndi ngAttri bute(Name:="ServicelSoap". [Namespace ]:="_
Public Class
Servicel
Inherits System.Web.Services.Protocols.SoapHttpClientProtocol
<System.Diagnostics.DebuggerStepThroughAttri
bute()> _
Public Sub New()
MyBase.New Me.Url ="align="left">End Sub
<System.Diagnostics.DebuggerStepThroughAttri
bute().
System.Web.Services.Protocols.
SoapDocumentMethodAttri bute _
("align="left">Use:=System.Web.Services.Description.
SoapBindingUse.Literal.
ParameterStyle:=System.Web.Services.
Protocols.SoapParameterStyle.Wrapped)>
_
Public Function GetWeather(ByVal city
As String)As String
Dimresults() As Object=Me.Invoke
("GetWeather". New Object 0 {city})
Return CType(results(0).
String)
End Function
<System.Diagnostics.
DebuggerStepThroughAttribute()>
_
Public Function
BeginGetWeather(ByVal city As String._
ByVal callback As System.AsyncCallback.
ByVal asyncState As Object) As System.IAsyncResult
Return
Me.Beginlnvoke("GetWeather",
New Object()
{city}.call back.asyncState)
End Function
<System.Diagnostics.DebuggerStepThroughAttributet)> _
Public Function
EndGetWeather(ByVal asyncResult
As System.IAsyncResult) As String
Dim results()As Object = Me.EndInvoke(asyncResult)
Return
CType(results(0), String)
End Function
End Class
Затем в проект
включается код класса (или ссылка
на него) и ссылки на сборки System. Web,
System. XML и System. Web.Services. Остается лишь
создать экземпляр
вспомогательного класса и вызвать
функцию GetWeather!
Теперь, когда вы
знаете, как получить результаты
обращения к web-службе, нетрудно
представить себе следующие
возможные шаги:
Перед
нами одно из проявлений той
концепции, которую сейчас активно
внедряет Microsoft, — Web как глобальная
сеть, через которую пользователь
легко получает доступ к любым
необходимым данным.