четверг, 26 января 2012 г.

Первая WCF служба

Теперь, когда у нас есть приложение, реализующее интерфейс, создадим веб-службу.



    В службе будет сосредоточена рабочая часть нашего проекта, его логика. В принципе, это можно реализовать и в приложении, но служба дает преимущество независимости рабочей части от интерфейса. В частности, из разных программ можно обращаться к одной и той-же службе, а не дублировать в каждой рабочий код.
Наша служба будет тестовая, все что она сможет, так это вернуть строку. Т.е. ответить на запрос. Пока большего не нужно.
    Чтобы не разбрасывать проекты по каталогам, создадим проект службы в ранее созданном решении с приложением. Для этого щелкнем правой клавишей по по названию решения в Обозревателе решений и в выпавшем меню выберем пункт Добавить - Создать проект.



    В открывшемся окне выбираем для C# проект "Приложение службы WCF".



   Указываем имя, в моем случае BnkLoadService, и нажимаем на кнопку ОК. После этого будет создан проект службы. Сейчас нас в нем интересуют 3 файла:  IService1.cs, Service1.svc и Web.config.

IService1.cs
     По умолчанию в этом файле описаны так называемые контракты операций и данных. Фактически - это интерфейсы, которые используются при вызове при обращении клиента к службе. При создании по умолчанию это выглядит так:

// ПРИМЕЧАНИЕ. Команду "Переименовать" в меню "Рефакторинг" можно использовать для одновременного изменения имени интерфейса "IService1" в коде и файле конфигурации.
    [ServiceContract]
    public interface IService1
    {

        [OperationContract]
        string GetData(int value);

        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);

        // TODO: Добавьте здесь операции служб
    }


    // Используйте контракт данных, как показано в примере ниже, чтобы добавить составные типы к операциям служб.
    [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; }
        }
    }

[OperationContract] - Указывает на то, что это интерфейс метода (операция службы).

[DataContract] - контракт передаваемых данных. Пока нам не нужен, потому смело удаляем.

Из контрактов операций оставляем только один вида:

        [OperationContract]
        string CheckService();

И чтобы два раза не вставать, рефакторингом переименовываем интерфейс IService1 в LoadInSQL. Сам файл придется переименовать руками в обозревателе решений.
Итак, мы описали интерфейс метода, который ничего не принимает и возвращает строку. Теперь нужно его реализовать. Это делается в

Service1.svc

    В нем мы видим класс, реализующий наш интерфейс:

    public class Service1 : LoadInSQL
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }
    }

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

        public string CheckService()
        {
            string result = "сервис доступен";

            return result;
        }

Прибная служба готова, теперь её нужно настроить. Делается это в

Web.config

 Раздел <bindings> заменяем на следующий:

    <bindings>
      <basicHttpBinding>
         <binding name="LoadServise">


           <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows"
             proxyCredentialType="Windows"           />
          </security>
          
         </binding>
      </basicHttpBinding>
    </bindings>

    Явно указываем его имя.
    Тип безопасности TransportCredentialOnly означает что используется самый простой тип безопасности на уровне транспорта (сами передаваемые сообщения не шифруются).
    В clientCredentialType описывается тип учетных данных, которые используются при проверке подлинности клиента с использованием проверки подлинности HTTP. В нашем случае используются данные домена, потому "Windows"
     В proxyCredentialType описывается то-же самое, но для случая работы клиента из-за прокси.

     Теперь описание самого сервиса. Выглядеть оно должно так:


    <services>
      <service name="BnkLoadService.LoadService">
        <host>
          <baseAddresses>
            <add baseAddress="http://name_server:8083"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="LoadServise" contract="BnkLoadService.LoadInSQL" />
      </service>
     
    </services>

 service name - имя нашего сервиса. формат имени: пространство_имен_сервиса.имя_класса
 baseAddresses - базовый адрес сервиса. состоит из имени сервера, на котором он будет размещен и порта.
endpoint  - описание конечной точки. То самое, ради чего все и делалось, именно конечная точка предоставляет клиенту операции. При описании указывается её адрес (address), который может быть пустым, как в нашем случае. В этом случае к сервису можно будет обращаться просто по адресу http://name_server:8083/LoadService.svc
binding и bindingConfiguration соответственно описанный нами ранее тип биндинга и указанное нами имя.
contract - указание на контракт в виде пространство_имен.имя_контракта

Раздел behaviors описывает поведение сервиса. Оставляем все как есть.

    Все готово, создаем для службы, по ранее описанному сценарию, сайт и разворачиваем на нем службу. Если теперь мы зайдем эксплорером по адресу http://name_server:8083/LoadService.svc, то увидим сообщение о том, что служба создана и короткую позстказку того, как её использовать.
    Остается один момент. По умолчанию служба исполняется от имени специально создаваемого для неё пользователя с ограниченными правами. В моём случае это проявляется в том, что при попытке создать в клиенте класс - обертку для службы я не могу пройти аутентификацию. Поэтому укажем пользователя, обладающего достаточно широкими правами. Это не безопасно, но для наших целей сгодится.
    Итак, снова открываем остнастку управления IIS-ом, идем в пулы приложений, выбираем нужный нам пул (его имя совпадает с именем сайта веб-службы), щелкаем по нему правой кнопкой и в выпавшем меню выбираем пункт "Дополнительные параметры...". В открывшейся форме раздел "Модель процесса", в нем пункт "Удостоверение", кликаем по строке "ApplicationPoolIdentity" и нажимаем появившуюся в правом конце строки кнопку.  В открывшейся форме выбираем пункт "Особая учетная запись", нажимаем "Установить" и вводим имя пользователя, имеющего достаточные права и его пароль. Все сохраняем, снова заходим эксплорером (лучше им) по адресу службы, чтобы окончательно убедится в её работоспособности. 

    Служба сконфигурирована и готова к работе.

Похожие посты:

Комментариев нет:

Отправить комментарий