Создание простейшей WCF-службы. Часть 2.

Примечание автора: эта статья была написана в районе 2008 года, и, скорее всего, она уже морально устарела. Однако, судя по отзывам, все еще кому-то полезна. Статья разделена на несколько частей.

Часть 1, Часть 2, Часть 3

Реализация сервиса

Итак, мы создали контракт нашей службы, теперь нужно этот контракт реализовать. Сразу переименуем файл Service1.cs в CalcService.cs (VS спросит, хотите ли вы переименовать тип, хранящийся в файле — нужно согласиться) и откроем его.

В xml-комментарии перед описанием класса сервиса видим то же самое предупреждение, что и в случае с интерфейсом. Удаляем его, а также все автоматически сгенерированное содержимое класса — оно нам не понадобится.

Теперь переводим курсор на имя наследуемого интерфейса, нажимаем Alt+Shift+F10 и в появившемся меню выбираем Implement interface ‘ICalcService’. Осталось лишь реализовать наш метод Calc:

Код метода Calc — Реализация службы CalcService

Код метода Calc — Реализация службы CalcService

WcfTestClient и WcfServiceHost

В состав .NET Framework 3.5 входит пара замечательных утилит для тестирования WCF-приложений: это WcfTestClient и WcfServiceHost. Расскажу о них поподробнее.

Первая из них — это универсальный тестовый клиент для WCF-сервисов, позволяющий вызывать методы службы, передавая им различные параметры, а также просматривать весь Xml-код запроса и ответа.

Примечание

Тестовый клиент, к сожалению, не поддерживает сеансы (о них подробнее в одной из следующих статей) и передачу композитных типов данных.

Так как тестовый клиент оперирует только с простыми типами данных, мы не сможем с помощью него проверить действие функции Calc.

Вторая утилита — это универсальное хост-приложение для WCF-сервисов. Она автоматически запускается студией при нажатии клавиши F5, когда стартовым проектом является библиотека WCF-службы. WcfServiceHost использует параметры сервиса из файла app.config библиотеки службы и, при наличии ошибок, сообщает об этом.

Попробуем запустить наше приложение, нажав клавишу F5. В системном трее появится значок WcfSvcHost. Дважды кликнув по нему, увидим такое окно:

WCF Service Host

WCF Service Host

В списке служб находится только одна служба — наш CalcService. Статус у него — «запущен», значит никаких ошибок на стороне службы не возникло. Если в статусе стоит «error» (ошибка), можно выбрать службу в списке и в поле Additional Information просмотреть подробное описание ошибки.

Второе окно, нас интересующее, — это тестовый клиент. После получения метаданных службы он выводит список методов в левой колонке. Как и следовало ожидать, наш метод Calc() тестовым клиентом не поддерживается — ведь он использует композитные типы данных.

WCF Test Client

WCF Test Client

Конфигурация службы

Настало время изучить файл конфигурации службы и разобраться с ее основными параметрами. Как мы помним из предыдущей статьи, точка соединения содержит в себе три основных объекта: адрес, привязку и контракт. Именно их мы сейчас и зададим.

Открываем файл app.config из проекта библиотеки службы и находим раздел <system.serviceModel>.

Перед тегом, открывающим данный раздел, видим следующий комментарий:

«<!— When deploying the service library project, the content of the config file must be added to the host’s app.config file. System.Configuration does not support config files for libraries. —>»

Переведу: при развертывании проекта библиотеки службы, содержимое конфигурационного файла должно быть добавлено в файл app.config приложения-хоста. Пространство имен System.Configuration не поддерживает конфигурационные файлы для библиотек. Но нас это пока не касается, так как мы используем утилиту WcfSvcHost, которая автоматически считывает параметры из файла конфигурации библиотеки.

Сейчас в разделе <system.serviceModel> видим только один подраздел — <services>, а в нем только один сервис — наш CalcService. У конфигурации службы есть два основных атрибута — это name, в котором нужно указать полное имя класса нашей службы (WcfCalcService.CalcService), и behaviorConfiguration — имя конфигурации поведения службы. Внутри описания службы объявлено две точки соединения — для самого сервиса и для его метаданных.

По умолчанию для точки соединения не указан адрес — установим его в «http://localhost/CalcService». В качестве привязки (binding) выберем пока basicHttpBinding (это привязка, которая обеспечивает просто транспорт по протоколу HTTP). В качестве контракта (contract) указан наш интерфейс — WcfCalcService.ICalcService. Также у точки соединения службы есть дочерний элемент <identity>, который служит для идентификации веб-приложения. Мы его пока проигнорируем.

Следующая точка соединения — это точка метаданных. Она используется для получения информации о контракте службы и сигнатурах ее методов. В качестве адреса у нее установлено значение «mex», без указания типа протокола. Это — относительный адрес, и для того, чтобы он работал, необходимо указание для него базового адреса. Что и сделано студией по умолчанию: в дочернем элементе точки соединения host\baseAddresses содержится элемент «add» с атрибутом baseAddress. Его значение мы установим в «http://localhost/CalcService». Теперь, при обращении по адресу «http://localhost/CalcService» клиент будет попадать к нашей службе, а по адресу «http://localhost/CalcService/mex» — к точке, обслуживающей метаданные.

Примечание

Заметьте, что точка соединения для метаданных использует специальные привязку и контракт — mexHttpBinding и IMetadataExchange соответственно. Менять эти значения не нужно.

Следующим за разделом <services> идет раздел <behaviors>, который описывает поведения служб. Для нашей службы там уже создан элемент «<behavior name=”WcfCalcService.Service1Behavior”>» (помните, в качестве значения атрибута behaviorConfiguration нашей службы как раз установлено «WcfCalcService.Service1Behavior»). В этом разделе содержится два элемента, перед каждым из которых видим увесистый комментарий:

1. To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment — Чтобы избежать раскрытия метаданных, установите значение ниже в false и точки соедидения метаданных перед развертыванием

2. To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information — Чтобы получать информацию об исключениях при возникновении ошибок в целях отладки, установите значение ниже в true. Установите значение ниже в false перед развертыванием для избежания раскрытия информации об исключительных ситуациях.

Нам до развертывания приложения еще далеко, поэтому пока оставляем все как есть.

Примечание

При возникновении необработанной исключительной ситуации на стороне службы, независимо от того, передаем мы подробную информацию об исключительной ситуации или нет, клиентский объект перейдет в состояние Faulted (об этом подробнее в одной из следующих статей), и соединение нужно будет создавать заново. Это очень неудобно, когда используются пошаговые сценарии с поддержкой сеансов, поэтому, для наглядности дальнейших демонстраций возможностей WCF мы не выкидываем Exception в нашем методе Calc, а включаем его в состав «результирующего» объектаCalcOperationResult.

Ниже приведен полный код файла app.config библиотеки службы:

WCF Service app.config file

WCF Service app.config file

 

 

 

 

Примечание

Если вы работаете в операционной системе Windows Vista, и попробуете сейчас запустить службу, появится окно приложения WcfSvcHost с сообщением об ошибке для службы калькулятора:

«System.ServiceModel.AddressAccessDeniedException: HTTP could not register URL http://+:80/CalcService/. Your process does not have access rights to this namespace (seehttp://go.microsoft.com/fwlink/?LinkId=70353 for details). → System.Net.HttpListenerException: Access is denied»

Это означает, что у процесса нет прав на регистрацию точки соединения по указанному адресу. Чтобы этой ошибки избежать, нужно просто запустить Visual Studio от имени администратора.

Если Вы нашли ошибку, пожалуйcта выделите ее и нажмите Shift + E или нажмите здесь чтобы информировать меня. Спасибо.

Добавить комментарий