
- •Лабораторная работа 6. Web-сервисы. Теория.
- •Практика Пример создания веб-сервиса в Visual Studio 7
- •Создание web - службы
- •Создание клиента для доступа к web службе.
- •Создание web-сервиса в более современных версиях.
- •Параметры атрибута WebService
- •Контрольные вопросы
- •Задания на группу
- •Список литературы
Создание клиента для доступа к 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)