创建用户定义的绑定Creating User-Defined Bindings

有多种方式可以创建系统未提供的绑定:There are several ways to create bindings not provided by the system:

  • 基于 CustomBinding 类(可向其中填充绑定元素的容器)创建一个自定义绑定。Create a custom binding, based on the CustomBinding class, which is a container that you fill with binding elements. 然后将自定义绑定添加到服务终结点。The custom binding is then added to a service endpoint. 可以通过编程方式或者在应用程序配置文件中创建自定义绑定。You can create the custom binding either programmatically or in an application configuration file. 若要从应用程序配置文件中使用绑定元素,该绑定元素必须扩展 BindingElementExtensionElementTo use a binding element from an application configuration file, the binding element must extend BindingElementExtensionElement. 有关自定义绑定的详细信息,请参阅自定义绑定CustomBindingFor more information about custom bindings, see Custom Bindings and CustomBinding.

  • 可以创建一个从标准绑定派生的类。You can create a class that derives from a standard binding. 例如,可以从 WSHttpBinding 派生一个类并重写 CreateBindingElements 方法,以获取绑定元素并插入自定义绑定元素或建立一个特定的安全值。For example, you can derive a class from WSHttpBinding and override CreateBindingElements method to obtain the binding elements and insert a custom binding element or establish a particular value for security.

  • 可以创建一个新的 Binding 类型来完全控制整个绑定实现。You can create a new Binding type to completely control the entire binding implementation.

绑定元素的顺序The Order of Binding Elements

发送或接收消息时,每个绑定元素都表示一个处理步骤。Each binding element represents a processing step when sending or receiving messages. 在运行时,绑定元素会创建必要的通道和侦听器,用以生成传出和传入通道堆栈。At runtime, binding elements create the channels and listeners necessary to build outgoing and incoming channel stacks.

有三种主要类型的绑定元素:协议绑定元素、编码绑定元素和传输绑定元素。There are three main types of binding elements: Protocol Binding Elements, Encoding Binding Elements and Transport Binding Elements.

协议绑定元素 – 这些元素表示对消息执行的更高级别的处理步骤。Protocol Binding Elements – These elements represent higher-level processing steps that act on messages. 由这些绑定元素创建的通道和侦听器可以添加、移除或修改消息内容。Channels and listeners created by these binding elements can add, remove, or modify the message content. 给定的绑定可以具有任意数量的协议绑定元素,每一个元素都从 BindingElement 继承。A given binding may have an arbitrary number of protocol binding elements, each inheriting from BindingElement. Windows Communication Foundation (WCF)包含多个协议绑定元素,其中ReliableSessionBindingElement包括SymmetricSecurityBindingElement和。Windows Communication Foundation (WCF) includes several protocol binding elements, including the ReliableSessionBindingElement and the SymmetricSecurityBindingElement.

编码绑定元素 – 这些元素表示消息与准备用于网络传输的编码之间的转换。Encoding Binding Element – These elements represent transformations between a message and an encoding ready for transmission on the wire. 典型的 WCF 绑定只包含一个编码绑定元素。Typical WCF bindings include exactly one encoding binding element. 编码绑定元素的示例包括 MtomMessageEncodingBindingElementBinaryMessageEncodingBindingElementTextMessageEncodingBindingElementExamples of encoding binding elements include the MtomMessageEncodingBindingElement, the BinaryMessageEncodingBindingElement, and the TextMessageEncodingBindingElement. 如果未对绑定指定编码绑定元素,则使用默认的编码。If an encoding binding element is not specified for a binding, a default encoding is used. 当传输协议是 HTTP 时,默认编码为文本,对于其他传输协议,默认编码为二进制。The default is text when the transport is HTTP and binary otherwise.

传输绑定元素 – 这些元素表示传输协议上编码消息的传输。Transport Binding Element – These elements represent the transmission of an encoding message on a transport protocol. 典型的 WCF 绑定只包含一个从继承的TransportBindingElement传输绑定元素。Typical WCF bindings include exactly one transport binding element, which inherits from TransportBindingElement. 传输绑定元素的示例包括 TcpTransportBindingElementHttpTransportBindingElementNamedPipeTransportBindingElementExamples of transport binding elements include the TcpTransportBindingElement, the HttpTransportBindingElement, and the NamedPipeTransportBindingElement.

创建新的绑定时,添加绑定元素的顺序很重要。When creating new bindings, the order of the added binding elements is important. 应始终按照以下顺序添加绑定元素:Always add binding elements in the following order:

Layer 选项Options 必填Required
事务流Transaction Flow System.ServiceModel.Channels.TransactionFlowBindingElement NoNo
可靠性Reliability System.ServiceModel.Channels.ReliableSessionBindingElement NoNo
安全性Security System.ServiceModel.Channels.SecurityBindingElement NoNo
复合双工Composite Duplex System.ServiceModel.Channels.CompositeDuplexBindingElement NoNo
编码Encoding 文本、二进制、MTOM、自定义Text, Binary, MTOM, Custom 是的*Yes*
传输Transport TCP、命名管道、HTTP、HTTPS、MSMQ、自定义TCP, Named Pipes, HTTP, HTTPS, MSMQ, Custom Yes

*由于每个绑定都需要一个编码,因此,如果未指定编码,WCF 将为你添加默认编码。*Because an encoding is required for each binding, if an encoding is not specified, WCF adds a default encoding for you. 对于 HTTP 和 HTTPS 传输,默认编码为 Text/XML,对于其他传输,默认编码为二进制。The default is Text/XML for the HTTP and HTTPS transports, and Binary otherwise.

创建新的绑定元素Creating a new Binding Element

除了由 WCF 提供的派生自BindingElement的类型之外,您还可以创建自己的绑定元素。In addition to the types derived from BindingElement that are provided by WCF, you can create your own binding elements. 这样,您就可以通过创建自己的、可与堆栈中其他的系统提供的类型组合的 BindingElement,自定义创建绑定堆栈的方式和进入其中的组件。This lets you customize the way the stack of bindings is created and the components that go in it by creating your own BindingElement that can be composed with the other system-provided types in the stack.

例如,如果实现一个 LoggingBindingElement 以提供将消息记录到数据库中的能力,则必须将其放置在通道堆栈中传输通道的上方。For example, if you implement a LoggingBindingElement that provides the ability to log the message to a database, you must place it above a transport channel in the channel stack. 在此情况下,应用程序创建一个将 LoggingBindingElementTcpTransportBindingElement 组合在一起的自定义绑定,如以下示例中所示。In this case, the application creates a custom binding that composed the LoggingBindingElement with TcpTransportBindingElement, as in the following example.

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

写入新的绑定元素的方式取决于元素的确切功能。How you write your new binding element depends on its exact functionality. 下面是一个示例:传输:UDP,提供如何实现一种绑定元素的详细说明。One of the samples, Transport: UDP, provides a detailed description of how to implement one kind of binding element.

创建新的绑定Creating a New Binding

可以通过两种方式使用用户创建的绑定元素。A user-created binding element can be used in two ways. 上一节演示了第一种方式:通过自定义绑定。The previous section illustrates the first way: through a custom binding. 自定义绑定允许用户基于任意一组绑定元素(包括用户创建的绑定元素)创建自己的绑定。A custom binding allows the user to create their own binding based on an arbitrary set of binding elements, including user-created ones.

如果在多个应用程序中使用绑定,则可创建自己的绑定并扩展 BindingIf you use the binding in more than one application, create your own binding and extend the Binding. 这样就避免了在每次使用时都需要手动创建自定义绑定。This avoids manually creating a custom binding every time you want to use it. 用户定义的绑定允许你定义绑定的行为并包括用户定义的绑定元素。A user-defined binding allows you to define the binding’s behavior and include user-defined binding elements. 并且它是预打包的:您不必在每次使用时都重新生成绑定。And it is pre-packaged: you do not have to rebuild the binding every time you use it.

用户定义的绑定至少必须实现 CreateBindingElements 方法和 Scheme 属性。At a minimum, a user-defined binding must implement the CreateBindingElements method and the Scheme property.

CreateBindingElements 方法返回一个新的 BindingElementCollection,其中包含绑定的绑定元素。The CreateBindingElements method returns a new BindingElementCollection that contains the binding elements for the binding. 此集合已经过排序,应首先包含协议绑定元素,接下来是编码绑定元素,再接下来是传输绑定元素。The collection is ordered, and should contain the protocol binding elements first, followed by the encoding binding element, followed by the transport binding element. 使用 WCF 系统提供的绑定元素时,必须遵循自定义绑定中指定的绑定元素排序规则。When using the WCF system-provided binding elements, you must follow the binding element ordering rules specified in Custom Bindings. 此集合不得引用在用户定义的绑定类中引用的对象;因此,绑定作者必须在每次调用 Clone() 时返回 BindingElementCollectionCreateBindingElementsThis collection should never reference objects referenced within the user-defined binding class; consequently, binding authors must return a Clone() of the BindingElementCollection on each call to CreateBindingElements.

Scheme 属性表示在绑定上使用的传输协议的 URI 方案。The Scheme property represents the URI scheme for the transport protocol in use on the binding. 例如, WSHttpBindingNetTcpBinding从其各自Scheme的属性返回 "http" 和 "net.tcp"。For example, the WSHttpBinding and the NetTcpBinding return "http" and "net.tcp" from their respective Scheme properties.

有关用户定义的绑定的可选方法和属性的完整列表,请参见 BindingFor a complete list of optional methods and properties for user-defined bindings, see Binding.

示例Example

本示例在派生自 SampleProfileUdpBindingBinding 中实现配置文件绑定。This example implements profile binding in SampleProfileUdpBinding, which derives from Binding. ReliableSessionBindingElement CompositeDuplexBindingElement TextMessageEncodingBindingElement UdpTransportBindingElement最多包含四个绑定元素:一个用户创建;三个系统提供的:、和。SampleProfileUdpBindingThe SampleProfileUdpBinding contains up to four binding elements within it: one user-created UdpTransportBindingElement; and three system-provided: TextMessageEncodingBindingElement, CompositeDuplexBindingElement, and 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();  
}  

双工协定的安全限制Security Restrictions with Duplex Contracts

不是所有绑定元素都彼此兼容。Not all binding elements are compatible with each other. 具体而言,安全绑定元素在用于双工协定时存在一些限制。In particular, there are some restrictions on security binding elements when used with duplex contracts.

单步安全One-Shot Security

通过将negotiateServiceCredential <消息 > 配置元素的属性设置为,可以实现 "一次" 安全,其中所有必需的安全凭据都通过将消息的属性设置为来false在单个消息中发送。You can implement "one-shot" security, where all the necessary security credentials are sent in a single message, by setting the negotiateServiceCredential attribute of the <message> configuration element to false.

单步身份验证无法与双工协定一起工作。One-shot authentication does not work with duplex contracts.

对于请求-答复协定,只有在安全绑定元素下的绑定堆栈支持创建 IRequestChannelIRequestSessionChannel 实例的情况下,单步身份验证才可以工作。For Request-Reply contracts, one-shot authentication works only if the binding stack below the security binding element supports creating IRequestChannel or IRequestSessionChannel instances.

对于单向协定,如果安全绑定元素下的绑定堆栈支持创建 IRequestChannelIRequestSessionChannelIOutputChannelIOutputSessionChannel 实例,则单步身份验证可以工作。For one-way contracts, one-shot authentication works if the binding stack below the security binding element supports creating IRequestChannel, IRequestSessionChannel, IOutputChannel or IOutputSessionChannel instances.

Cookie 模式安全上下文标记不能与双工协定一起使用。Cookie mode security context tokens cannot be used with duplex contracts.

对于请求-答复协定,只有在安全绑定元素下的绑定堆栈支持创建 IRequestChannelIRequestSessionChannel 实例的情况下,Cookie 模式安全上下文标记才可以工作。For Request-Reply contracts, cookie-mode security context tokens work only if the binding stack below the security binding element supports creating IRequestChannel or IRequestSessionChannel instances.

对于单向协定,如果安全绑定元素下的绑定堆栈支持创建 IRequestChannelIRequestSessionChannel 实例,则 Cookie 模式安全上下文标记可以工作。For one-way contracts, cookie-mode security context tokens works if the binding stack below the security binding element supports creating IRequestChannel or IRequestSessionChannel instances.

会话模式安全上下文标记Session-mode Security Context Tokens

如果安全绑定元素下的绑定堆栈支持创建 IDuplexChannelIDuplexSessionChannel 实例,则会话模式 SCT 适用于双工协定。Session mode SCT works for duplex contracts if the binding stack below the security binding element supports creating IDuplexChannel or IDuplexSessionChannel instances.

如果安全绑定元素下的绑定堆栈支持创建 IDuplexChannelIDuplexSessionChannelIRequestChannelIRequestSessionChannel 实例,则会话模式 SCT 适用于请求-答复协定。Session mode SCT works for Request-Reply contracts if the binding stack below the security binding element supports creating IDuplexChannel, IDuplexSessionChannel, IRequestChannel or IRequestSessionChannel, instances.

如果安全绑定元素下的绑定堆栈支持创建 IDuplexChannelIDuplexSessionChannelIRequestChannelIRequestSessionChannel 实例,则会话模式 SCT 适用于单向协定。Session mode SCT works for 1-way contracts if the binding stack below the security binding element supports creating IDuplexChannel, IDuplexSessionChannel, IRequestChannel or IRequestSessionChannel instances.

派生自标准绑定Deriving from a Standard Binding

也许可以扩展一个现有的系统提供的绑定,而不用创建一个全新的绑定类。Instead of creating an entirely new binding class, it may be possible for you to extend one of the existing system-provided bindings. 与上一个示例非常类似,必须重写 CreateBindingElements 方法和 Scheme 属性。Much like the preceding case, you must override the CreateBindingElements method and the Scheme property.

请参阅See also