Основы ASP.NET 2.0

         

Пользование web-службой


В Интернете существует множество готовых web-служб. Сайты http://uddi.microsoft.com, http://www.webservicelist.com/ — каталоги различных сервисов. Чтобы получить информацию от web-службы, нужно только послать HTTP-запрос, в теле которого находится SOAP-сообщение. Запрос к службе http://www.webservicex.net/globalweather.asmx на получение прогноза погоды в Москве выглядит так:

POST /globalweather.asmx HTTP/1.1 Host: www.webservicex.net Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: "http://www.webserviceX.NET/GetWeather"

<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <GetWeather xmlns="http://www.webserviceX.NET"> <CityName>Moscow</CityName> <CountryName>Russian</CountryName> </GetWeather> </soap:Body> </soap:Envelope>

Заголовок запроса отличается от запросов, которые обычно посылают браузеры, прежде всего полем Content-Type — text/xml; а не text/html; В теле запроса находится SOAP-сообщение.

Сервис в ответ оправляет XML-документ:

<?xml version="1.0" encoding="utf-8" ?> <string xmlns="http://www.webserviceX.NET"> <?xml version="1.0" encoding="utf-16"?> <CurrentWeather> <Location>Moscow / Vnukovo , Russia (UUWW) 55-39N 037- 16E</Location> <Time>Aug 07, 2006 - 04:30 AM EDT / 2006.08.07 0830 UTC</Time> <Wind> from the E (080 degrees) at 11 MPH (10 KT):0</Wind> <Visibility> greater than 7 mile(s):0</Visibility> <SkyConditions> overcast</SkyConditions> <Temperature> 66 F (19 C)</Temperature> <DewPoint> 55 F (13 C)</DewPoint> <RelativeHumidity> 68%</RelativeHumidity> <Pressure> 29.85 in.


Hg (1011 hPa)</Pressure> <Status>Success</Status> </CurrentWeather></string>

Чтобы сделать проект ASP .NET потребителем web-сервиса, первым делом в проекте надо создать web-ссылку на удаленный объект — web-сервис. Выберите в меню Website пункт Add Web Reference. Появится диалоговое окно.


увеличить изображение
Рис. 16.1. 

Введите URL web-сервиса с параметром wsdl в текстовое поле www.webservicex.net/globalweather.asmx?WSDL. В файл web.config добавляется настройка приложения:

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <appSettings> <add key="weather.webservicex.www.globalweather" value="http://www.webservicex.net/globalweather.asmx"/> </appSettings> <connectionStrings>

Чтобы определить доступные по этому адресу web-сервисы, используется алгоритм DISCO.

При этом создается файл globalweather.wsdl. WSDL (Web Service Discovery Language) — это язык описания web-сервисов. Это еще один тип XML-документов.

<?xml version="1.0" encoding="utf-8"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://www.webserviceX.NET" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://www.webserviceX.NET" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> <wsdl:types> <s:schema elementFormDefault="qualified" targetNamespace="http://www.webserviceX.NET"> <s:element name="GetWeather">



Создание web-ссылки добавляет в конфигурационный файл еще одну запись:

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <appSettings> <add key="weather.webservicex.www.globalweather" value="http://www.webservicex.net/globalweather.asmx"/> </appSettings>

Чтобы облегчить работу с web-сервисами, используют прокси-классы. Они предоставляют разработчикам удобные функции и берут на себя преобразование их параметров в элементы XML, после чего посылают запрос web-сервису через Интернет.

Утилита wsdl поможет преобразовать его в прокси-класс:

wsdl globalweather.wsdl

Прокси-класс необходимо поместить в папку App_Code, после чего объекты этого класса можно создавать в коде любой страницы.

Программу wsdl можно запустить и удаленно:

wsdl http://www.webservicex.net/globalweather.asmx?wsdl

В созданном файле объявлен класс GlobalWeather, наследник System.Web.Services.Protocols.SoapHttpClientProtocol. Функции этого класса предназначены как для синхронного, так и для асинхронного вызова. Например, синхронная функция GetWeather запрашивает строковые параметры с названием города и страны и возвращает строку с XML-документом. В сервисе есть и другая функция, с помощью которой можно узнать доступные города для каждой страны:

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http:/ /www.webserviceX.NET/GetWeather", RequestNamespace="http://www.webserviceX.NET", ResponseNamespace="http://www.webserviceX.NET", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wr apped)] public string GetWeather(string CityName, string CountryName) { object[] results = this.Invoke("GetWeather", new object[] { CityName, CountryName}); return ((string)(results[0])); }





Это текст можно использовать на странице:

<form id="form1" runat="server"> <br /> <asp:Button ID="Button1" runat="server" Text="А теперь про- гноз погоды" OnClick="Button1_Click" /> <br /> <br /> <asp:Label ID="lblTemp" runat="server" Text="Температура в Москве "></asp:Label> </form>

protected void Button1_Click(object sender, EventArgs e) { // создание экземпляра прокси-класса GlobalWeather gw = new GlobalWeather(); // запрос функции web-сервиса string xmlstring = gw.GetWeather("Moscow", "Russia"); XmlDocument doc = new XmlDocument(); // загрузка ответа в документ doc.LoadXml(xmlstring); // doc.ChildNodes.Item(0) — это XML-заголовок // doc.ChildNodes.Item(1) — тело XmlNode child = doc.ChildNodes.Item(1); XmlElement el = child["Temperature"]; lblTemp.Text += el.InnerText; }


SOAP


Для взаимодействия с web-сервисами применяется протокол SOAP, основанный на XML. Можно было бы использовать просто XML, но это слишком свободный формат, в нем каждый документ фактически создает свой язык. SOAP — это соглашение о формате XML-документа, о наличии в нем определенных элементов и пространств имен.

SOAP позволяет публиковать и потреблять сложные структуры данных, например DataSet. В то же самое время его легко изучить. Текущая версия SOAP — 1.2.

SOAP — это Простой Протокол Обмена Данными (Simple Object Access Protocol). SOAP создан для того, чтобы облегчать взаимодействие приложениям через HTTP. Это особый независимый от платформы формат обмена сообщениями через Интернет. Сообщение SOAP — это обычный XML-документ. Стандарт SOAP разрабатывает консорциум W3C.

SOAP-сообщение состоит из конверта (envelope), заголовка (header) и тела (body). Элементы body и envelope должны присутствовать всегда, а header необязателен. Элемент envelope — корневой. Элемент header может содержать специфичную для данного приложения информацию. В документе, сгенерированном web-сервисом, может присутствовать элемент ault, который описывает ошибку работы.

POST /WebSite5/WebService.asmx HTTP/1.1 Host: localhost Content-Type: application/soap+xml; charset=utf-8 Content-Length: length

<?xml version="1.0" encoding="utf-8"?> <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> <soap12:Body> <HelloWorld xmlns="http://localhost/webservices" /> </soap12:Body> </soap12:Envelope>

В ASP .NET можно легко как создать web-службу, так и пользоваться готовой.



Создание web-сервиса


Создание web-сервиса немногим отличается от создания обычной страницы. Есть два варианта: можно создать отдельный проект или вставить web-сервис в существующий проект. В первом случае другие проекты должны создавать web-ссылку, чтобы обращаться к сервисам этого проекта. Файл web-сервиса имеет расширение asmx. Файл web-сервиса должен начинаться с директивы WebService. Класс web-сервиса может быть потомком класса System.Web.Services.WebService.

Если при объявлении web-сервиса вы породили его от класса System.Web.Services.WebService, то вы автоматически получаете доступ к глобальным объектам приложения ASP .NET Application, Context, Session, Server и User. Если же вы создавали класс web-сервиса как-то иначе — ничего страшного. Вы все равно можете получить доступ к вышеперечисленным свойствам с помощью соответствующих свойств статического HttpContext.Current.

Методы, которые сервис предоставляет для вызова с помощью SOAP-запросов, должны иметь атрибут WebMethod. У атрибута WebMethod существует 6 свойств, влияющих на работу метода.

Создадим новое приложение в VS .NET и добавим к нему файл web-сервиса Customers.asmx.

Файл nw.asmx содержит единственную строку — директиву WebService, которая утверждает, что этот файл — web-сервис. Этот файл меняться не будет:

<%@ WebService Language="C#" CodeBehind="~/App_Code/Customers.cs" Class=" Customers " %>

У директивы WebService всего 4 возможных атрибута. CodeBehind, который раньше был атрибутом и директивы Page, определяет физический путь к файлу отделенного кода.


Атрибут Class обязателен и определяет класс, который реализует функциональность web-сервиса. Debug и Language аналогичны тем же атрибутам директивы Page:

Файл с расширением .asmx — точка входа создаваемого web-сервиса.

Класс System.Web.Services.WebService, которые обычно наследуется класс сервиса, предоставляет доступ к глобальным объектам Application и ViewState.

Весь код web-сервиса будет располагаться в codebehind-файле Service.asmx.cs. Изначально этот файл (созданный в Visual Studio .NET) имеет следующий вид:

<%Class="WebService" %>

using System; using System.Web; using System.Collections; using System.Web.Services; using System.Web.Services.Protocols;

/// <summary> /// Summary description for WebService /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class MyWebService : System.Web.Services.WebService {

public WebService () {

//Uncomment the following line if using designed compo- nents //InitializeComponent(); }

[WebMethod] public string HelloWorld() { return "Hello World"; }

}

Атрибут WebServiceBinding удостоверяет соответствие откликов web-сервиса WS-I Basic Profile 1.0 release требованиям организации WS-I (Web Services Interoperability organization), которая занимается вопросами межплатформенной совместимости web-сервисов.

Метод HelloWorld создан Visual Studio в качестве примера начинающим разработчикам.

Web-сервис может состоять из множества классов.



Однако только один класс в web- сервисе может иметь методы, помеченные атрибутом WebMethod (которые можно вызывать через SOAP-запросы).

Когда страница web-сервиса запрашивается в браузере, он возвращает автоматически генерируемую страницу помощи по данному сервису. Откроем в браузере страницу WebService.asmx. В браузере появится страница:


Рис. 16.2. 

ASP .NET для отображения web-сервиса использует файл шаблона DefaultWsdlHelpGenerator.aspx, расположенный в папке <%SYSTEM_ROOT%\Microsoft.NET\Framework\<version>\CONFIG. На выводимой странице web-сервиса есть название web-сервиса, ссылка на описание сервиса и список web-методов, объявленных в web-сервисе. Остальная часть страницы посвящена тому, что необходимо изменить пространство имен по умолчанию для web-сервиса http://tempuri.org/ на собственное. Поступим как рекомендуют — изменим параметр Namespace атрибута WebService класса web- сервиса:

[WebService(Namespace = "http://Lection-16.asp2.intuit. org/")]

Кроме того, в атрибуте WebService можно задать свойства Name и Description, и они появятся на странице помощи по web-сервису.



Также представлены примеры ответов вызова web-метода.

Протестируем нашу работу с помощью страницы web-сервиса:

<?xml version="1.0" encoding="utf-8" ?> <string xmlns="http://localhost/webservices">Hello World</string>

От такого web-сервиса нет особенной пользы, поэтому создадим новый сервис nw и вместо метода HelloWorld напишем метод, который обращается к базе данных Northwind и возвращает DataSet:

[WebService(Name="Northwind web service", Description = "Web-сер- вис для работы с клиентами", Namespace = "http://intuit.asp2.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class nw : System.Web.Services.WebService {

public nw() { } string strConn = @"Data Source=.\SQLExpress;Initial Catalog=Northwind;Integrated Security=True"; [WebMethod(MessageName = "Get Orders of Customers", Description = "Web-метод для работы с заказами", CacheDuration = 600)] public DataSet GetCustOrders(string CustomerID) { SqlConnection myConn = new SqlConnection(strConn); SqlDataAdapter myData = new SqlDataAdapter("CustOrdersOrdersDetails", myConn); myData.SelectCommand.CommandType = CommandType.StoredProcedure; myData.SelectCommand.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.Char, 5)); myData.SelectCommand.Parameters["@CustomerID"].Value = CustomerID;

DataSet ds = new DataSet(); myData.Fill(ds); ds.Tables[0].TableName = "Orders"; ds.Tables[1].TableName = "OrderDetails"; ds.Relations.Add(ds.Tables[0].Columns["OrderID"], ds.Tables[1].Columns["OrderID"]); return ds; }



Другие аргументы атрибуты WebMethod:

1. CacheDuration определяет промежуток времени в секундах, на которое кэшируется web-сервис. По умолчанию равно 0, что значит, что кэширование отключено.

В этом объявлении значение, возвращаемое методом GetCustOrders, кэшируется на 10 минут.

2. Description — описание метода, которое выводится на странице сервиса под ссылкой на страницу метода.

3. EnableSession позволяет включить поддержку сессий. По умолчанию поддержка сессий в web-сервисах отключена. Чтобы включить ее, определите web-метод следующим образом:

[WebMethod(EnableSession=true)]

4. MessageName определяет уникальное имя метода. Позволяет использовать перегруженные функции с одним именем, но разными сигнатурами.

5. TransactionOption управляет поддержкой транзакций. По умолчанию она отключена. Web-сервисы ограниченно поддерживают транзакции, то есть веб-сервис может порождать транзакцию, но при этом не может быть участником другой транзакции. Возможные значения аргумента — Disabled, NotSupported, Supported, Required, и RequiresNew. Если вызывается web-метод с TransactionOption, установленным в Required или RequiresNew, а в нем вызывается другой web-метод с такими же установками, каждый из этих методов инициирует свою транзакцию.

Метод GetCustOrders возвращает тип DataSet. Посмотрим, как он помещается в SOAP:

<?xml version="1.0" encoding="utf-8" ?> - <DataSet xmlns="http://intuit.asp2.org/"> - <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> - <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> - <xs:complexType> - <xs:choice minOccurs="0" maxOccurs="unbounded"> - <xs:element name="Orders"> - <xs:complexType> - <xs:sequence> <xs:element name="OrderID" type="xs:int" minOccurs="0" /> <xs:element name="OrderDate" type="xs:dateTime" minOccurs="0" /> <xs:element name="RequiredDate" type="xs:dateTime" minOccurs="0" /> <xs:element name="ShippedDate" type="xs:dateTime" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> ... <xs:selector xpath=".//OrderDetails" /> <xs:field xpath="OrderID" /> </xs:keyref> </xs:element> </xs:schema> <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msda- ta" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" /> </DataSet>



Это почти готовая схема xsd. Из нее можно, например, сгенерировать класс бизнес-логики.

Использовать наш сервис можно и удаленно, и из приложения, в котором он находится.

Создадим форму, которая будет отображать полученный DataSet в элементе управления GridView:

<form id="form1" runat="server"> <div> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT CustomerID, CompanyName FROM Customers Order by CompanyName" ProviderName="<%$ ConnectionStrings:NorthwindConnectionString.ProviderName %>"></asp:SqlDataSource> <asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="SqlDataSource1" DataTextField="CompanyName" DataValueField="CustomerID"> </asp:DropDownList></div> <asp:Button ID="Button1" runat="server" Text="Get Orders" /> <asp:GridView ID="GridView1" runat="server"> </asp:GridView> </form>

Имя компании выбирается из выпадающего списка. После нажатия на кнопку вызывается обработчик:

protected void Button1_Click(object sender, EventArgs e) { localhost.Northwindwebservice orders = new localhost.Northwindwebservice(); GridView1.DataSource = orders.GetCustOrders(DropDownList1.SelectedValue); GridView1.DataBind(); }

Стать потребителем этого сервиса могло бы и обычное Windows-приложение, написанное на C++, C# или Visual Basic.Web-сервисы тоже могут пользоваться услугами других web-сервисов.


Web-службы


В процессе эволюции Интернета появилась необходимость в создании распределенных приложений. Приложения, установленные на компьютере, обычно используют библиотеки, размещенные на нем. Одну библиотеку могут использовать несколько программ. Можно ли размещать аналоги библиотек в Интернете, чтобы разные сайты могли их вызывать? Оказывается, да.

Предприятия на своих страницах предоставляют разнообразную информацию. Например, со своего сайта www.Ford.com компания "Форд" публикует информацию о моделях и ценах. Дилер этой компании хотел бы иметь эту информацию и на своем сайте. Web-служба позволяет сайту-потребителю получать информацию с сайта-поставщика. Сайт-потребитель показывает эту информацию на своих страницах. Код для генерации этой информации написан один раз, но может использоваться многими потребителями. Данные представлены в простом текстовом виде, поэтому ими можно пользоваться независимо от платформы.

Web-сервисы широко используются и в Desktop, и в Интернет-приложениях. Они сами по себе являются не приложениями, а источниками данных для приложений. У них отсутствует пользовательский интерфейс. Web-сервисами необязательно пользоваться через сеть — они могут быть частью проекта, в котором используются.

Web-сервисы — это функциональность и данные, предоставляемые для использования внешними приложениями, которые работают с сервисами посредством стандартных протоколов и форматов данных. Web-сервисы полностью независимы от языка и платформы реализации. Технология Web-сервисов является краеугольным камнем программной модели Microsoft .NET.


Это дальнейшее развитие компонентного программирования CORBA и DCOM. Однако для использования таких компонентов необходимо регистрировать их в системе потребителя. Для web-служб это не требуется. Компоненты хорошо работают в локальных сетях. Протокол HTTP не приспособлен для вызова удаленных процедур (RPC). Даже в одной организации часто используются разные операционные системы, которые могут взаимодействовать только через HTTP.

Было предпринято несколько попыток создания языка коммуникации между разнородными системами — DCOM, CORBA, RMI, IIOP. Они не получили всеобщего распространения, так как каждый из них продвигался разными производителями и поэтому был привязан к технологиям конкретного изготовителя. Никто не хотел принимать чужой стандарт. Чтобы выйти из этой дилеммы, несколько компаний договорились выработать независимый от производителя стандарт обмена сообщениями через HTTP. В мае 2000 года компании IBM, Microsoft, HP, Lotus, SAP, UserLand и другие обратились к W3C и выдвинули SOAP в качестве кандидата на такой стандарт. SOAP произвел революцию в области разработки приложений, объединив два стандарта Интернета — HTTP и XML.


Эта лекция затронула основы создания


Эта лекция затронула основы создания и потребления web-сервисов ASP .NET. Web-сервисы помогают обмену данными между фирмами и в локальных сетях, независимо от операционной системы.