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


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

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

  • Создать пользовательскую привязку на основе класса 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, определенный пользователем

Да

*Поскольку кодирование обязательно для каждой привязки, если элемент кодирования не задан, то 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();
}

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

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

Одноступенчатый способ обеспечения безопасности

Можно реализовать «одноступенчатый» способ обеспечения безопасности, при котором все необходимые учетные данные безопасности запрашиваются в одном сообщении, присвоив атрибуту negotiateServiceCredential элемента конфигурации <message> значение 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.

См. также

Справочник

Binding

Основные понятия

Пользовательские привязки