Web Service в Visual Studio 10 и клиент на Delphi 7

Part 1. Веб-сервис (Web Service) в Visual Studio 10 называется “WCF Service Application”.

Сразу после создания нового сервиса он содержит класс Service1 (в файле Service1.svc.cs), реализующий интерфейс IService1 (в файле IService1.cs), в котором объявлены два публичных демонстрационных метода GetData и GetDataUsingDataContract и композитный тип данных CompositeType. Веб-сервис можно сразу запустить (Debug). В окне броузера появится следующее сообщение: "Служба создана... необходимо создать клиент... Это можно сделать запустив программу svcutil.exe..."

В результате запуска svcutil.exe будет создан файл Service1.cs, который нужно добавить в тестовый проект (я сделал консольное тестовое приложение TestApplication1). В References тестового проекта нужно добавить System.Runtime.Serialization и System.ServiceModel. Пример вызова веб-службы см. на рисунке выше. 
Теперь немного про развертывание веб-службы на сервере IIS. Можно воспользоваться визардом (Publish), а можно сделать все "ручками":
  1. Установить .Net Framework 4.0, если он еще не установлен.
  2. Создать каталог на сайте, например C:\inetpub\wwwroot\Service1.
  3. Скопировать туда Service1.svc файлы Service1.svc, Web.Config и папку bin с файлами WcfService1.dll и WcfService1.pdb.
  4. Дать права “Чтение, Чтение и выполнение” пользователю IIS (IUSR)  на каталог Service1 и все скопированные в него файлы/подкаталоги.
  5. В диспетчере служб IIS в контекстном меню каталога Service1 выбрать “Преобразовать в приложение”. В диалоге “Добавление приложения” нажать кнопку “Выбрать…” справа от “Пул приложений”, выбрать пул приложений с версией среды .Net Framework соответствующей веб-сервису (ASP .NET v4.0), и нажать Ok. Каталог Service1 будет преобразован в приложение.

Иногда сразу же приложение не хочет работать в IIS (как случилось и у меня) с формулировкой типа “HTTP Error 404.3 - Not Found The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map.” В таком случае помогает выполнение команды ServiceModelReg.exe -i. ServiceModelReg.exe находится в C:\Windows\Microsoft .NET\Framework\v4.0.30319. Там же находится aspnet_regiis.exe. Он помогает в том случае, если .Net 4 вдруг оказывается не зарегистрированным (см. картинку ниже) и по этой причине веб-сервис не запускается.

Part 2. Создание клиента для веб-сервиса на Delphi 7.

1. Сервис должен использовать привязку basicHttpBinding, а не wsHttpBinding. Регулируется это в Web.Config. Для его правки в Visual Studio 10 можно воспользоваться утилитой WCF Service Configuration Editor (можно выбрать пункт Edit WCF Configuration из контекстного меню для Web.Config).

2. Необходимо обновить утилиту импорта WSDL. Взять ее можно здесь: http://cc.embarcadero.com/item/24535. Пользоваться ею просто, например так:

    WSDLImp.exe -P http://localhost:2708/Service1.svc?wsdl

В результате будет создан файл Service1.pas, который нужно подключить к проекту клиента в Delphi 7. Пользоваться очень просто:

uses Service1.pas;
var
Client: IWcfService1;
ws: WideString;
begin
Client := GetIWcfService1(True, 'http://localhost:2708/Service1.svc?wsdl');
ws := Client.GetDate(10);
MessageBoxW(0, PWideChar(ws), 'Result', MB_ICONINFORMATION);
end;

3. Delphi 7 BUG. При попытке обратиться к веб-сервису из клиента, написанного на Delphi 7, может возникать Access Violation (см. картинку ниже). Возникает эта ошибка не везде. У меня на Windows 7 ее нет, а на Windows Server 2008 - проявилась.

Фикс для этой ошибки находится в том же архиве, что и новая утилита импорта WSDL (http://cc.embarcadero.com/item/24535). НО НЕ ТОРОПИТЕСЬ заменять ваши исходники SOAP на файлы из архива. Этот “патч” что-то лечит, а что-то калечит :-) У меня при его использовании перестали передаваться в веб-сервис строковые параметры вызова (в значениях параметров всегда содержался null). Для того, чтобы справиться с ошибкой Access Violation, нам необходимы только два файла из этого патча: PrivateHeap.pas и Rio.pas. Их (только их!) нужно добавить в Delphi-проект клиента веб-сервиса.

===

Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru