Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа 6 - web сервисы.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
396.8 Кб
Скачать

Создание клиента для доступа к web службе.

Web – служба может быть использована приложением работающим на любой платформе. Создадим простейшее windows приложение конторе будет использовать созданную web – службу для перевода курса валют. Само приложение может находиться где угодно поэтом у этап создания windows приложения пропустим и приступим к подключению web – службы к нашему приложению.

В Solution Explorer -> Add Reference нажимаем правую кнопку мыши и выбираем Add Web Reference. В появившемся окне (рис. 3-5) выбираем Web services on the local machine, так как наша созданная web служба находиться на локальном компьютере. Если есть локальная сеть и служба доступна из нее то искать её естественно нужно в Browse UDDI Servers on the local network

Рисунок 3‑10

Далее в появившемся списке выбираем нашу web – службу. После того, как система САМА найдет функции нужно добавить их в проект кнопкой Add Reference (рис 3-6).

Поле Web Reference Name можно оставить нетронутым, но для того что бы внести смысловую нагрузку в имя ссылки на службу её можно придать смысловую нагрузку.

Рисунок 3‑11

В результате проведенных действий у нас есть проект windows приложения, которое связанно с разработанной ранtе web службой. Теперь необходимо разаработать интерфейс самого приложения. В данном примере будем использовать следующий вид приложения.

Рисунок 3‑12

При нажатии на кнопку «Перевести» будем выполнять следующие действия для вызова функции web – службы.

private void button1_Click(object sender, System.EventArgs e)

{

localhost.Service1 serv= new webServiceClient.localhost.Service1();

textBox3.Text = serv.convertRub2Euro(Convert.ToDouble(textBox1.Text),Convert.ToDouble(textBox2.Text)).ToString();

}

В результате получим приложение которое будет использовать web – службу, а точнее функцию web – службы для работы. Так как для примера был выбран достаточно простой вариант задания, это вовсе не значит, что способности web служб ограничиваются подобными возможностями…

Создание web-сервиса в более современных версиях.

Итак, как же выглядит веб сервис для разработчика? Первое – файл web-сервиса имеет расширение asmx. Второе – создание web-сервиса немногим отличается от создания веб-формы в .NET Framework. Третье – файл веб сервиса должен начинаться с директивы WebService. Четвертое – класс web-сервиса может (но не должен) быть потомком класса System.Web.Services.Webservice. Ну и последнее (пока что) – метод, вызываемый через веб, должен имет атрибут WebMethod.

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

Файл nw.asmx содержит единственную строку – директиву WebService, которая утверждает, что этот файл – действительно веб сервис. Этот файл меняться не будет, так что можете взглянуть на него и пока забыть :).

<%@ WebService Language="c#" Class="WebServicesExample.nw" %>

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

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Diagnostics;

using System.Web;

using System.Web.Services;

namespace WebServicesExample

{

/// <summary>

/// Summary description for nw.

/// </summary>

public class nw : System.Web.Services.WebService

{

public nw()

{

//CODEGEN: This call is required by the ASP.NET Web Services Designer

InitializeComponent();

}

#region Component Designer generated code

//Required by the Web Services Designer

private IContainer components = null;

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

private void InitializeComponent()

{

}

/// <summary>

/// Clean up any resources being used.

/// </summary>

protected override void Dispose( bool disposing )

{

if(disposing && components != null)

{

components.Dispose();

}

base.Dispose(disposing);

}

#endregion

// WEB SERVICE EXAMPLE

// The HelloWorld() example service returns the string Hello World

// To build, uncomment the following lines then save and build the project

// To test this web service, press F5

// [WebMethod]

// public string HelloWorld()

// {

// return "Hello World";

// }

}

}

ASP.NET для отображения web-сервиса использует файл шаблона DefaultWsdlHelpGenerator.aspx, расположенный в папке %SYSTEM_ROOT%\Microsoft.NET\Framework\<номер версии Microsoft .NET Framework>\CONFIG.

Теперь рассмотрим строение web-сервиса, что называется, шаг за шагом.

В первой (и единственной, если вы пишете с использованием технологии codebehind) строке asmx файла, как и в случае с aspx-файлом, расположена директива ASP.NET, указывающая на тип данного файла, язык, на котором написан код, и имя класса для файла. Например строка для написанного нами web-сервиса следующая:

<%@ WebService Language="c#" Class="WebServicesExample.nw" %>

где директива WebService указывает на то, что данный файл является web-сервисом, а атрибуты Language=”c#” и Class=”WebServicesExample.nw” указывают на то, что класс web-сервиса написан на C# и полное имя класса – WebServicesExample.nw.

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

Атрибут WebMethod имеет шесть свойств, влияющих на работу web-метода. Рассмотрим их:

Description

Данное свойство служит для общего описания web-метода. Вы можете присвоить данному свойству любую текстовую строку. Значение свойства Description выводится на странице описания web-сервиса.

EnableSession

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

[WebMethod(EnableSession=true)]

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

Рассмотрим работу с объектами Application и Session на примере. Напишем небольшой web-сервис с двумя web-методами – setSessionVar (принимает 2 строковых параметра – имя переменной сессии и ее значение, и устанавливает переменную сессии) и getSessionVar (принимает строковый параметр – имя сессии, и возвращает значение переменной сессии):

[WebMethod(EnableSession=true)]

public void setSessionVar(string name, string val)

{

Session[name] = val;

}

[WebMethod(EnableSession=true)]

public string getSessionVar(string name)

{

return (string) Session[name];

}

Не забывайте, что ASP.NET определяет сессию по идентификатору сессии, хранящемуся в cookie. Так что приведенный выше пример будет успешно работать из страницы web-сервиса, но если попробовать вызывать методы этого web-сервиса из .NET приложения через прокси-класс, то вы с удивлением обнаружите, что вызов метода getSessionVar не возвращает никакого значения, так как использование web-сервисов с помощью проки-класса по умолчанию не использует куки для сохранения информации.

Чтобы .NET приложение могло работать с сессией с помощью web-сервиса, необходимо добавить в код, вызывающий методы web-сервиса, работу с cookie. И это не так уж сложно, как кажется на первый взгляд :).

Создадим Windows приложение, добавим в него Web Reference на созданный ранее web-сервис и добавим интерфейс для установки переменных сессии с помощью метода setSessionVar и получения значения переменной сессии с помощью getSessionVar. Объявим также в класс приватную переменную cookie типа CookieContainer (класс CookieContainer описан в модуле System.Net). В конструкторе класса проиницализируем эту переменную. Теперь для того, чтобы вызовы методов web-сервиса были в одной сессии, необходимо просто перед вызовом web-метода присвоить значение cookie свойству CookieContainer класса web-сервиса.

Полностью код вызова веб методов с использованием cookie представлен ниже (прокси-класс, сгенерированный для web-сервиса, имеет название localhost1.testService1):

private CookieContainer cookie;

public Form1()

{

InitializeComponent();

cookie = new CookieContainer();

}

private void btnSetValue_Click(object sender, System.EventArgs e)

{

localhost.session session = new localhost.session();

session.CookieContainer = cookie;

session.setSessionVar(txtSessionName.Text, txtSessionValue.Text);

}

private void btnGetValue_Click(object sender, System.EventArgs e)

{

localhost.session session = new localhost.session();

session.CookieContainer = cookie;

txtSessionValue.Text = session.getSessionVar(txtSessionName.Text);

}

MessageName

Свойство MessageName позволяет назначать web-методу имя, отличное от того, которое ему было назначено при написании класса web-сервиса.

Существует возможность создавать в web-сервисе web-методы с одинаковыми именами. Но при попытке просмотра страницы такого web-сервиса будет сгенерирована ошибка. Свойство MessageName используется именно в этих случаях.

Допустим кроме веб метода GetCustOrders с одним параметром (код клиента) у нас объявлен еще один метод GetCustOrders, принимающий кроме кода клиента также вилку дат и возвращающий DataSet с информацией о заказах, дата которых находится между указанными датами

[WebMethod(Description=" Возвращает список заказов для указанного клиента ")]

public DataSet GetCustOrders(string CustomerID)

{

...

}

[WebMethod(MessageName="GetCustOrdersByDate")]

public DataSet GetCustOrders(string CustomerID, DateTime startDate, DateTime endDate)

{

...

}

Теперь, хотя оба web-метода и имеют одинаковое имя, все равно есть возможность использовать страницу web-сервиса. При этом в прокси классе оба метода естесственно будут определены с именем GetCustOrders.

TransactionOption

Web-сервисы ограниченно поддерживают транзакции. С помощью свойства TransactionOption можно управлять тем, как ваш метод использует транзакции. Это свойство может принимать следующие значения:

Disabled

Веб метод выполняется вне транзакции

NotSupported

То же самое

Supported

Если транзакция существует – метод выполняется в контексте этой транзакции, если же нет – выполнение идет вне транзакции

Required

Метод требует наличия транзакции для выполнения. При этом всегда создается новая транзакция (аналогично RequiresNew).

RequiresNew

Метод требует создания новой транзакции. Каждый раз при вызове метода создается новая транзакция.

Слово «ограниченно» означает, что веб сервис может порождать транзакцию, но при этом не может быть участником другой транзакции. Если вызывается веб метод с TransactionOption установленным в Required или RequiresNew, а в нем вызывается другой веб метод с такими же установками, каждый из этих методов инициирует свою транзакцию.

По умолчанию свойство TransactionOption установлено в Required.

При нормальном завершении работы метода транзакция считается выполненной. Чтобы прервать выполнение транзакции, сгенерируйте исключение. В веб методе не нужно вызывать методы SetComplete и SetAbort.

CacheDuration

Сказать, что кеширование веб сервисов просто означало бы покривить душой. Кешировать веб сервисы не просто, а очень просто. Одним словом, все, что нужно для того, чтобы активизировать кеширование веб сервиса, это использовать параметр CacheDuration атрибута WebMethod с указанием промежутка времени в секундах, на которое кешируется веб сервис.

Ниже представлен пример обхъявления, кеширующий возвращаемое методом GetCustOrders значение на 10 минут.

[WebMethod(CacheDuration=600)]

public DataSet GetCustOrders(string CustomerID)

BufferResponse

Свойство BufferResponse позволяет управлять буферизацией ответа web-метода. По умолчанию результат выполнения буферизируется и отправляется клиенту только после того, как он полностью сформирован. Однако если ваш web-метод очень долго выполняется, возможно, имеет смысл отключать буферизацию результата.

Для отключения буферизации результата используйте следующее объявление web-метода:

[WebMethod(BufferResponse=false)]

public DataSet GetCustOrders(string CustomerID)