Создание привязок User-Defined

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

  • Создайте пользовательскую привязку на основе класса CustomBinding, который служит контейнером для заполнения элементами привязки. Затем пользовательская привязка добавляется в конечную точку службы. Пользовательскую привязку можно создать программным способом или в файле конфигурации приложения. Чтобы использовать элемент привязки из файла конфигурации приложения, элемент привязки должен расширять BindingElementExtensionElement. Дополнительные сведения о пользовательских привязках см. в разделе "Пользовательские привязки " и CustomBinding.

  • Можно создать класс, производный от стандартной привязки. Например, можно создать класс, наследующий от WSHttpBinding, и переопределить метод CreateBindingElements, чтобы получить элементы привязки и вставить пользовательский элемент привязки или определить конкретное значение безопасности.

  • Вы можете создать новый Binding тип, чтобы полностью контролировать всю реализацию привязки.

Порядок элементов привязки

Каждый элемент привязки представляет шаг обработки при отправке или получении сообщений. В процессе выполнения элементы привязки создают каналы и прослушиватели, необходимые для формирования стеков исходящих и входящих каналов.

Существует три основных типа элементов привязки: элементы привязки протокола, элементы привязки кодировки и элементы транспортной привязки.

Элементы привязки протокола — эти элементы представляют шаги обработки более высокого уровня, которые действуют на сообщениях. Каналы и прослушиватели, созданные этими элементами привязки, могут добавлять, удалять или изменять содержимое сообщения. У данной привязки может быть произвольное количество элементов привязки протокола, каждое из которых наследуется BindingElement. Windows Communication Foundation (WCF) включает несколько элементов привязки протокола, включая ReliableSessionBindingElement и .SymmetricSecurityBindingElement

Элемент привязки кодирования — эти элементы представляют преобразования между сообщением и кодировкой, готовой для передачи на проводе. Типичные привязки WCF включают ровно один элемент привязки кодировки. Примеры элементов привязки кодирования включают MtomMessageEncodingBindingElement, BinaryMessageEncodingBindingElement, и TextMessageEncodingBindingElement. Если элемент привязки кодировки не указан для привязки, используется кодировка по умолчанию. По умолчанию используется текст, если транспорт — HTTP, и двоичный в противном случае.

Элемент привязки транспорта — эти элементы представляют передачу кодированного сообщения по транспортному протоколу. Типичные привязки WCF включают ровно один элемент транспортной привязки, который наследуется от TransportBindingElement. Примеры элементов привязки транспорта включают в себя TcpTransportBindingElement, HttpTransportBindingElement и NamedPipeTransportBindingElement.

При создании новых привязок порядок добавленных элементов привязки важен. Всегда добавляйте элементы привязки в следующем порядке:

Уровень Опции Обязательно
Поток транзакций System.ServiceModel.Channels.TransactionFlowBindingElement нет
Надежность System.ServiceModel.Channels.ReliableSessionBindingElement нет
Безопасность System.ServiceModel.Channels.SecurityBindingElement нет
Составной дуплекс System.ServiceModel.Channels.CompositeDuplexBindingElement нет
Кодировка Текст, бинарный, MTOM, пользовательский Да*
Транспорт TCP, именованные каналы, HTTP, HTTPS, MSMQ, Custom Да

*Поскольку для каждой привязки требуется кодировка, если кодировка не указана, WCF добавляет для вас кодировку по умолчанию. Значением по умолчанию является Text/XML для транспортов HTTP и HTTPS, а в противном случае — двоичный формат.

Создание нового элемента Привязки

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

Например, если вы реализуете LoggingBindingElement, который предоставляет возможность записи сообщений в базу данных, необходимо поместить его над транспортным каналом в стеке каналов. В этом случае приложение создает пользовательское связывание, которое состоит из LoggingBindingElement и TcpTransportBindingElement, как в следующем примере.

Binding customBinding = new CustomBinding(
  new LoggingBindingElement(),
  new TcpTransportBindingElement()
);

Способ записи нового элемента привязки зависит от его точной функциональности. Один из примеров, транспорт: UDP, содержит подробное описание реализации одного типа элемента привязки.

Создание новой привязки

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

Если вы используете привязку в нескольких приложениях, создайте собственную привязку и расширьте ее Binding. Это избавляет от необходимости каждый раз, когда вы хотите его использовать, вручную создавать пользовательскую привязку. Определяемая пользователем привязка позволяет определить поведение привязки и включить определяемые пользователем элементы привязки. И это предварительно упаковано: вам не нужно заново настраивать связывание каждый раз при его использовании.

Как минимум, определяемая пользователем привязка должна реализовывать CreateBindingElements метод и Scheme свойство.

Метод CreateBindingElements возвращает новый BindingElementCollection, содержащий элементы привязки. Коллекция упорядочена и должна содержать элементы привязки протокола, а затем элемент привязки кодирования, а затем элемент привязки транспорта. При использовании элементов привязки, предоставляемых системой WCF, необходимо следовать правилам упорядочения элементов привязки, указанным в настраиваемых привязках. Эта коллекция никогда не должна ссылаться на объекты, на которые ссылается определяемый пользователем класс привязки; следовательно, авторы привязки должны возвращать Clone() и BindingElementCollection при каждом вызове CreateBindingElements.

Свойство Scheme представляет схему URI для транспортного протокола, используемого в привязке. Например, WSHttpBinding и NetTcpBinding возвращают http и net.tcp из соответствующих Scheme свойств.

Полный список необязательных методов и свойств для определяемых пользователем привязок см. в разделе Binding.

Пример

В этом примере реализуется привязка профиля в SampleProfileUdpBinding, которая наследуется от Binding. SampleProfileUdpBinding содержит до четырех элементов привязки: один элемент, созданный пользователем UdpTransportBindingElement; и три системных элемента: TextMessageEncodingBindingElement, CompositeDuplexBindingElement, и ReliableSessionBindingElement.

public override BindingElementCollection CreateBindingElements()
{
    BindingElementCollection bindingElements = new BindingElementCollection();
    if (ReliableSessionEnabled)
    {
        bindingElements.Add(session);
        bindingElements.Add(compositeDuplex);
    }
    bindingElements.Add(encoding);
    bindingElements.Add(transport);
    return bindingElements.Clone();
}

Ограничения безопасности с дуплексными контрактами

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

One-Shot Безопасность

Вы можете реализовать «единоразовую» защиту, при которой все необходимые учетные данные безопасности передаются в одном сообщении, задав negotiateServiceCredential атрибут <элемента конфигурации сообщения> в значение false.

Однофакторная проверка подлинности не работает с дуплексными контрактами.

Для контрактов Request-Reply проверка подлинности выполняется только в том случае, если стек привязки ниже элемента привязки безопасности поддерживает создание экземпляров IRequestChannel или IRequestSessionChannel.

Для односторонних контрактов единовременная аутентификация работает, если стек привязки ниже элемента безопасности поддерживает создание экземпляров IRequestChannel, IRequestSessionChannel, IOutputChannel или IOutputSessionChannel.

Маркеры контекста безопасности режима cookie нельзя использовать с дуплексными контрактами.

Для контрактов Request-Reply маркеры контекста безопасности в режиме cookie работают только в том случае, если стек привязки под элементом привязки безопасности поддерживает создание экземпляра IRequestChannel или IRequestSessionChannel.

Для односторонних контрактов маркеры контекста безопасности в режиме cookie работают, если стек привязки под элементом привязки безопасности поддерживает создание экземпляров IRequestChannel или IRequestSessionChannel.

Маркеры контекста безопасности в режиме сеанса

Режим сеанса SCT работает для дуплексных контрактов, если стек привязок под элементом привязки безопасности поддерживает создание экземпляра IDuplexChannel или IDuplexSessionChannel.

SCT-режим сеанса работает для контрактов Request-Reply, если стек привязки под элементом привязки безопасности поддерживает создание экземпляров IDuplexChannel, IDuplexSessionChannel, IRequestChannel или IRequestSessionChannel.

SCT-режим сеанса работает для однонаправленных контрактов, если стек привязки под элементом привязки безопасности поддерживает создание экземпляров IDuplexChannel, IDuplexSessionChannel, IRequestChannel или IRequestSessionChannel.

Производный от стандартной привязки

Вместо создания совершенно нового класса привязки можно расширить одну из существующих системных привязок. Как и в случае с предыдущим примером, необходимо переопределить метод CreateBindingElements и свойство Scheme.

См. также