Web Service

На главную страницу

logo.gif

Введение в WCF Web Service

Аннотация: Данная статья написана когда автор столкнулся с необходимостью использования Web сервисов в поставляемом в фирму ПО. До этого как то обходились без Web сервисов. Литературы в инете по данному вопросу много и много прочитано, но очень многое еще и остается темными пятнами. Поэтому, по мере накопления знаний, статья будет модифицироваться и уточняться. Автор будет благодарен за любые замечания и уточнения. Адрес почты - найдете на главной странице сайта по ссылке "Об авторе".

Весь материал разработан в Visual Studio Net 2010 в Windows 7

В начало

Параграф 1. Вместо предисловия

Веб-служба, веб-сервис (web service) — программная система, идентифицируемая строкой URI, чьи общедоступные интерфейсы определены на языке XML (eXtensible Markup Language). Благодаря веб-сервисам функции любой программы могут стать доступными через Интернет - программы могут обращаться к какой-нибудь программе, работающей на другом сервере (т.е. к веб-сервису), и использовать ответ, полученный от нее на своем веб-сайте, или в приложении. Веб-службы обеспечивают взаимодействие программных систем независимо от платформы. Они основаны на базе открытых стандартов и протоколов. Благодаря использованию XML достигается простота разработки и отладки веб-служб.

Используемые стандарты

Для создания Web сервиса в Visual Studio Net воспользуемся темплатой "WCF Server Application" (меню "File/New Project") и дадим ему имя "MyFirstWebService" (Рис.1). Сразу отметим, что мы создаем непривычный для предыдущих Net Framework web сервис - WCF (Windows Communication Foundation). WCF — программный фреймворк, используемый для обмена данными между приложениями входящими в состав .NET Framework. До Net Framework 4 использовался немного другой сервис (его мы можем найти, если сменим в окне ".Net Framework 4", на ".Net Framework 3.5" и найдем темплату ASP.NET Web Service Application). Создав проект на базе этой темплаты, мы найдем привычные .asmx файлы, которых, как видно из Рис.2. нет в проекте WCF сервиса. Это не просто смена имен файлов, а смена технологии - WCF делает возможным построение безопасных и надёжных транзакционных систем через упрощённую унифицированную программную модель межплатформенного взаимодействия. Комбинируя функциональность существующих технологий .NET по разработке распределённых приложений (ASP.NET XML Web Services — ASMX, WSE 3.0, .NET Remoting, .NET Enterprise Services и System.Messaging). WCF предоставляет единую инфраструктуру разработки, повышающую производительность и снижающую затраты на создание безопасных, надёжных и транзакционных Web-служб нового поколения.

В начало

Параграф 2. Создаем WCF web сервис

Собственно говоря мы уже приступили к его созданию (см.выше). На Рис.1. показан выбор темплаты и задание имени службы - "MyFirstWebService" и таким же оставим и имя проекта. Если мы планируем тестировать службу перед применением и будем создавать Host и клиентское приложение для работы, то имена службы и проекта следует разделить. После нажатия кнопки "OK" служба практически создана.

s1.jpg

Рис.1. Создание Web сервиса WCF

s2.jpg

Рис.2. Создание Web сервиса WCF

Сервис WCF представлен основным файлом Service1.svc.cs (Рис.2.), где размещены методы сервиса, IService1.cs - методы интерфейса и два файла Web.config для двух режимов. Кроме того обратим внимание на закладке References и в используемых пространствах имен на ссылки System.ServiceModel:

using System.ServiceModel;
using System.ServiceModel.Web;

Стартовый пример показывает и то, как вводить данные собственных типов ([DataContract]):

namespace MyFirstService
{
 [ServiceContract]
 public interface IService1
 {
   [OperationContract]
   string GetData(int value);

   [OperationContract]
   CompositeType GetDataUsingDataContract(CompositeType composite);
 }
 [DataContract]
 public class CompositeType
 {
  bool boolValue = true;
  string stringValue = "Hello ";
  [DataMember]
  public bool BoolValue
  {
      get { return boolValue; }
      set { boolValue = value; }
  }

  [DataMember]
  public string StringValue
  {
      get { return stringValue; }
      set { stringValue = value; }
  }
 }
}

Так как сервис создан, нажав F5, мы можем посмотреть его презентационное представление и указание на то, что делать дальше. А нажав ссылку svcutil.exe http://localhost:3818/Service1.svc?wsdl - можем посмотреть с помощью "svcutil.exe" его XML содержание (.wsdl файл, в котором описывается, что сервис может делать и с какими данными он может работать) - (Рис.3).

s3.jpg

Рис.3. Web сервис WCF

В XML коде мы можем найти:

Для отладки сервиса можно использовать "WCF Test Client". Выберем узел "Service1.svc" и в его контекстном меню выберем пункт "Set As Start Page" и нажмем F5. Теперь появится окно "WCF Test Client" (Рис.4.). В нем мы можем просмотреть и протестировать наши методы и посмотреть их XML реализацию.

s4.jpg

Рис.4. Использование WCF Test Client

Наполним сервис своим содержанием, например, поставим ему задачу проверять валидность почтовых адресов, для чего в файле IService1.cs оставим один контакт(OperationContract).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace MyFirstWebService
{
    
    [ServiceContract]
    public interface IService1
    {
     [OperationContract]
     string ValidateAddress(string address);
    }   
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace MyFirstWebService
{
 public class Service1 : IService1
 {
  public string ValidateAddress(string address)
  {
   string pattern = @"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@(([0-9a-zA-Z])+([-\w]*[0-9a-zA-Z])*\.)+[a-zA-Z]{2,9})$";
   if (Regex.IsMatch(address, pattern))
   {
     return address + " is valid";
   }
   else
   {
    return address + " is no valid";
   }
  }
 }
}

В принципе, если мы уверены в работоспособности службы, то мы можем ее опубликовать.

В начало

Параграф 3. Публикация Web сервиса

Опубликуем наш сервис. Режим компиляции выберем "Release", на всякий случай перекомпилируем службу (меню "Build/RebuildMyFirstService") и далее выбираем меню "Build/Publish MyFirstService" (Рис.5.):

s5.jpg

Рис.5. Публикация службы

На Рис.6. показано, что мы публикуем службу туда, куда IIS нам определил сайт по умолчанию (Default Web Site). Это сделано для удобства. В принципе, когда мы работаем "на дядю", то есть, сайт у нас на другой машине, то можно опубликовать в любое место, а затем скопировать файлы сборки в нужное место, а далее с помощью тамошнего IIS сделать директорию сборки приложением. Еще один момент - не рекомендуется менять имя сервиса.

s6.jpg

Рис.6. Публикация службы

Теперь превратим нашу папку сборки в приложение IIS.

s7.jpg

Рис.7. Создание приложения

s8.jpg

Рис.8. Создание приложения

Осталось проверить работоспособность службы, как показано на Рис.9., и доступность кода XML, как это делали выше, нажав ссылку http://localhost/MyFirstWebService/Service1.svc?wsdl:

Отметим, что для выборки службы мы использовали вызов

http://localhost/MyFirstWebService/service1.svc

s9.jpg

Рис.9. Проверка службы

В начало

Параграф 4. Создание клиентских Windows и Web приложений, использующих Web службу

Далее создадим новый проект - либо консольное, либо WindowsApplication или Asp.Net приложение, которое будет обращаться к службе. У нас будет возможность проверить, являются ли действительными указанные адреса электронной почты, или, по крайней мере удовлетворяющими нашему регулярному выражению. Я создал обычное ASP.Net Web приложение (Рис.10.):

s10.jpg

Рис.10. Создание ASP.NET приложения

Поместим на форму два контрола: Button и Label и добавим ссылку на наш сервис как показано на Рис.11-17.

s11.jpg

Рис.11. Создание ASP.NET приложения

s12.jpg

Рис.12. Добавление ссылки на сервис

s13.jpg

Рис.13. Добавление ссылки на сервис

s14.jpg

Рис.14. Добавление ссылки на сервис

Если сервис не отображается - введите его адрес и нажмите зеленую кнопочку справа:

s15.jpg

Рис.15. Добавление ссылки на сервис

Задайте имя сервису для приложения и нажмите кнопочку "Add Reference":

s16.jpg

Рис.16. Добавление ссылки на сервис

s17.jpg

Рис.17. Ссылка на сервис добавлена

Добавим код в приложение, как показано на Рис.18.

s18.jpg

Рис.18. Код приложения

Испытаем приложение - результат показан на Рис.19.

s19.jpg

Рис.19. Выполнение ASP.NET приложения

Проделав все то же cамое для Windows приложения, получим тот же результат (Рис.20):

s20.jpg

Рис.20. Выполнение Windows приложения

В начало

Параграф 6. Совмещение проектов для удобства отладки Web сервисов

Возьмем наш проект в том виде, в котором он изображен на Рис.5. - иначе на момент когда мы создали наш сервис. Переименуем решение из MyFirstService в FirstService, воспользовавшись контекстным меню, пункт "Rename". К решению добавим, например Console Application (контекстное меню решения, пункты "Add/New Project" - темплата "Console Application" (закладка "Windows")). Не меняя имени приложения нажмем кнопку "OK". Получим результат, показанный на Рис.21.

s21.jpg

Рис.21. Сервис и консольное приложение

Кликаем в Solution Exploreре на узле CondoleApplication1 и в контекстном иеню выбираем "Add Service Reference" (Рис.22.).

s22.jpg

Рис.21. Сервис и консольное приложение

Далее повторяем шаги, показанные на Рис.12-14. На шаге Рис.14. выбираем "Web Services in This Solution" (Рис.23.).

s23.jpg

Рис.23. Добавление сервиса из текущего проекта

Выбираем Service1 и даем ему имя, например "myservice", нажимаем кнопку "Add Reference" (Рис.24.).

s24.jpg

Рис.24. Добавление сервиса из текущего проекта

В проет ConsoleApplication добавляем пространство имен:

using ConsoleApplication1.myservice;

и код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication1.myservice;

namespace ConsoleApplication1
{
 class Program
 {
  static void Main(string[] args)
  {
    Service1 webservice = new Service1();
    Console.WriteLine("Insert email adress!"); 
    string str = Console.ReadLine();
    str= webservice.ValidateAddress(str);
    Console.WriteLine(str);
    str  = Console.ReadLine();
  }
 }
}

Кликаем в Solution Exploreре на узле CondoleApplication1 и в контекстном иеню выбираем пункт "Set as Startup Project". Запускаем приложение и получаем резельтат, как показано на Рис.25.

s25.jpg

Рис.25. Исрользование Web сервиса в целях отладки приложения

После отладки приложения мы точно также можем публиковать наш сервис, как это описано выше.

В начало

Параграф 7. О параметрах вызова методов Web Service

Пока мы работали с методом, в котором все параметры строки, проблем не было с вызовом метода, ровно, как и с тем как, и сколько параметров определено в файле интерфейса, и с тем, как и столько параметров используется. Однако. Если мы зададим в IService1.cs контакт с параметрами типа int или другими, отличными от строковых, например:

[OperationContract]
int square(int value);

При этом в файле Service1.svc.cs определим его, как метод возведения числа в квадрат:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace MyFirstService
{
 public class Service1 : IService1
 {
  public int square(int p)
  {
   return (p*p);
  }
 }
}

Вновь добавим web ссылку на service в консольном приложении, как это сделано в параграфе 6. И теперь попытаемся использовать наш метод:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication1.myService;
namespace ConsoleApplication1
{
 class Program
 {
  static void Main(string[] args)
  {
   Service1 webservice = new Service1();
   Console.WriteLine("Insert number!");
   string str = Console.ReadLine();
   int a=webservice.square(Convert.ToInt32(str));
   Console.ReadLine();
}

То получим ошибку:

Error	1	No overload for method 'square' takes 1 arguments	
E:\Service\FirstService\ConsoleApplication1\Program.cs	18	21	ConsoleApplication1

Кликнув правой кнопкой мышки на методе "square" и выбрав в контекстном меню "Go To Defination", попадем в файл "Reference.cs", где увидим, что наш метод получил серьезное преобразование:

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/IService1/square", 
    RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", 
    Use=System.Web.Services.Description.SoapBindingUse.Literal, 
    ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public void square(int value, [System.Xml.Serialization.XmlIgnoreAttribute()] bool valueSpecified, 
    out int squareResult, [System.Xml.Serialization.XmlIgnoreAttribute()] out bool squareResultSpecified) 
{
 object[] results = this.Invoke("square", new object[]{value,valueSpecified});
 squareResult = ((int)(results[0]));
 squareResultSpecified = ((bool)(results[1]));
}

По крайней мере, параметров в методе стало 4. Прием первого параметра методом выглядит как обычно, а возврат результата осуществляется через параметр типа "out". Два параметра "xxxSpecified" определяют действительность параметров в сериализованном XML документе. Эти преобразования как раз и связаны с передачей XML документа в сериализованном виде.

В MSDN написано: "Сериализация XML– это процесс преобразования открытых свойств и полей объекта в серийный формат (в данном случае в формат XML) для хранения и транспортировки. Десериализация пересоздает объект в его исходном состоянии из вывода XML. Сериализацию можно представить в качестве способа сохранения состояния объекта в поток или буфер. Например, ASP.NET использует класс XmlSerializer для кодирования сообщений веб-службы XML.... схема включает использование двух параметров - один параметр для использования (System.ComponentModel.DefaultValueAttribute) значения по умолчанию, другой параметр для использования специального шаблона с целью создания логического поля, определяемого XmlSerializer, и с целью применения XmlIgnoreAttribute к полю. Шаблон создается в форме propertyNameSpecified. Например, при наличии поля с именем "MyFirstName" (Мое имя) также будет создано поле с именем "MyFirstNameSpecified" (Мое имя указано), инструктирующее XmlSerializer о необходимости генерирования элемента XML с именем "MyFirstName"

Таким образом, мы вынуждены мириться с изменением определенных в интерфейсе методов, например, в нашем примере выход из положения прост:

static void Main(string[] args)
{
 Service1 webservice = new Service1();
 Console.WriteLine("Insert number!");
 string str = Console.ReadLine();
 //Так работать не будет
 //int a = webservice.square(Convert.ToInt32(str));
 int rez=0;
 bool f = false;
 //Так работает
 webservice.square(Convert.ToInt32(str),true,out rez,out f);
 Console.WriteLine(rez.ToString());
 Console.ReadLine();
}

Молчанов Владислав 15.12.2011г.

logo.gif

В начало страницы

На главную страницу

К началу книги


Сайт управляется системой uCoz