Основы ASP.NET 2.0

       

Создание 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-сервисов.


Содержание раздела