Простая 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-службе, нетрудно представить себе следующие возможные шаги:

  • объединение результатов нескольких обращений к web-службам в одном файле;
  • применение к результату запроса преобразований XSL и построение новых страниц с HTML-кодом при помощи web-служб, работающих на разных сайтах.
  • Перед нами одно из проявлений той концепции, которую сейчас активно внедряет Microsoft, — Web как глобальная сеть, через которую пользователь легко получает доступ к любым необходимым данным.