Поделиться через


Создание пользовательских привязок

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

  • Создать пользовательскую привязку на основе класса 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 No
Надежность System.ServiceModel.Channels.ReliableSessionBindingElement No
Контроль доступа System.ServiceModel.Channels.SecurityBindingElement No
Составной дуплексный System.ServiceModel.Channels.CompositeDuplexBindingElement No
Кодировка Текстовая, двоичная, MTOM, пользовательская Да*
Транспорт TCP, именованные каналы, HTTP, HTTPS, MSMQ, определенный пользователем Да

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

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

Помимо типов, производных от 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.

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

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

При односторонних контрактах одноступенчатая проверка подлинности работает в том случае, если стек привязки, находящийся после элемента безопасности привязки, поддерживает возможность создания экземпляров IRequestChannel, IRequestSessionChannel, IOutputChannel или IOutputSessionChannel.

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

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

При односторонних контрактах маркеры контекста безопасности режима "cookie" работают в том случае, если стек привязки, находящийся после элемента безопасности привязки, поддерживает возможность создания экземпляров IRequestChannel или IRequestSessionChannel.

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

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

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

Маркеры контекста безопасности режима сеанса работают для односторонних контрактов тогда, когда стек привязки, находящийся после элемента безопасности привязки, поддерживает возможность создания экземпляров IDuplexChannel, IDuplexSessionChannel, IRequestChannel или IRequestSessionChannel.

Класс, производный от стандартной привязки

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

См. также