WCF 4.5 Bindings Comparison | Types Of Bindings In WCF 4.5 | WCF Tutorial

Address, Binding, and Contract are commonly referred to as the "ABCs" of WCF. Address is specifies the absolute or relative path or the URI (Uniform Resource Indicator) of the service. In WCF, Binding is used to specify the transport channel that your service uses. Contractspecifies the contract that the service endpoint exposes to the outside world. In this section, I focus on the the supported types of Binding in WCF 4.5.
The following are the types of transport channels supported:
  • HTTP
  • TCP
  • Message Queuing
  • Pipes
Table 1 lists the various binding classes in WCF, the transport and message modes, message encoding types, security modes, and transaction support.


Binding Class
Transport
Transport Mode
Message Mode
Message Encoding
Security Mode
Reliable Messaging
Transaction Flow
BasicHttpBinding
HTTP
Yes
Yes
Text
None
Not Supported
Not Supported
WSHttpBinding
HTTP
Yes
Yes
Text
Message
Disabled
WS-AtomicTransactions
WSDualHttpBinding
HTTP
No
Yes
Text
Message
Enabled
WS-AtomicTransactions
WSFederationHttpBinding
HTTP
No
Yes
Text
Message
Disabled
WS-AtomicTransactions
NetTcpBinding
TCP
Yes
Yes
Binary
Transport
Disabled
OleTransactions
NetPeerTcpBinding
P2P
Binary
Transport
Not Supported
Not Supported
NetNamedPipesBinding
Named Pipes
Yes
No
Binary
Transport
Not Supported
OleTransactions
NetMsmqBinding
MSMQ
Yes
Yes
Binary
Message
Not Supported
Not Supported
MsmqIntegrationBinding
MSMQ
Yes
No
Not Supported
Transport
Not Supported
Not Supported
Table 1: Binding classes in WCF.
Let's now have a quick look at all the supported binding types in WCF.

BasicHttpBinding

BasicHttpBinding is the simplest type of binding used. It provides support for both HTTP and HTTPS protocol. The following code snippet illustrates how this type of binding can be specified.

?
1
2
3
4
5
6
7
8
9
<bindings>
  <basicHttpBinding>
    <binding name="DDJServiceBinding">
      <security mode="Transport">
        <transport clientCredentialType="None"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

WsHttpBinding

WsHttpBinding is an enhanced form of binding that encrypts the SOAP message. It provides support for both HTTP and HTTPS protocols, and both Text and MTOM encoding methods.

?
1
2
3
4
5
6
<binding name=" DDJServiceBinding ">
  <security mode="TransportWithMessageCredential">
    <transport clientCredentialType="None"/>
    <message clientCredentialType="IssuedToken"/>
  </security>
</binding>

NetTcpBinding

NetTcpBinding is based on the TCP protocol and is a type of binding that provides support for both transactions and security. It uses transport security by default.

?
1
2
3
4
5
6
7
8
  <client>
    <endpoint name="Demo" address="net.tcp://localhost:1234/DDJService"
      binding="netTcpBinding" contract="IDDJService" >
      <identity>
        <servicePrincipalName value=”DDJService/Joydip-PC” />
      </identity>
    </endpoint>
</client>


NetNamedPipeBinding

In WCF, NetNamedPipeBinding is used for cross-process communication. This type of binding uses transport security and supports message encryption and signing. Here's an example that shows how you can specify this type of binding for your service:

?
1
2
3
4
5
6
7
8
9
10
<services>
<service name="DDJService" behaviorConfiguration="DDJService Behavior">
        <host>
          <baseAddresses>
            <add baseAddress="net.pipe://localhost:1234/DDJService "/>
          </baseAddresses>
        </host>
<endpoint address="" binding="netNamedPipeBinding" contract="IDDJService "></endpoint>
</service>
</services>

And here is how the netNamedPipeBinding client configuration would look:

?
1
2
3
4
5
<client>
  <endpoint
  binding="netNamedPipeBinding" contract="IDDJService "></endpoint>
</client>


MsmqIntegrationBinding

MsmqIntegrationBinding is used in situations where you would like to have your service and client interoperate with non-WCF MSMQ clients.

NetMsmqBinding

The NetMsmqBinding type of binding is used in a cross-machine environment. It employs MSMQ as the transport channel.

NetPeerTcpBinding

NetPeerTcpBinding is used for peer-to-peer network applications where services and service clients can intercommunicate. The following code snippet illustrates how you can configure this type of binding:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<endpoint
  binding="netPeerTcpBinding" 
  bindingConfiguration="netp2pBinding"
  contract="IDDJService">
  <bindings>
        <netPeerTcpBinding>
          <binding name="netP2P" >
            <resolver mode="Pnrp" />
            <security mode="None" />
          </binding>
  </netPeerTcpBinding>
</bindings>

WsDualHttpBinding

If you need support for Duplex Message Exchange (where services can communicate with their clients through callbacks), you need to use WsDualHttpBinding. In essence, it isWsHttpBinding with support for a Duplex Message Exchange pattern.

WsFederationHttpBinding


In WCF, WsFederationHttpBinding is used for federated security.

Custom Binding


You can implement your own custom binding class for additional transport protocols, security, etc. To implement a custom binding class, you need to derive a class fromSystem.ServiceModel.Channels.Binding class:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System.ServiceModel.Channels;
namespace DDJService
{
    public class DDJSecureBinding : System.ServiceModel.Channels.Binding
    {
        private HttpTransportBindingElement transport = new HttpTransportBindingElement();
        private BinaryMessageEncodingBindingElement encoding = new BinaryMessageEncodingBindingElement();
        public override BindingElementCollection CreateBindingElements()
        {
            BindingElementCollection bindingElements = new BindingElementCollection();
            bindingElements.Add(this.encoding);
            bindingElements.Add(this.transport);
            return bindingElements;
        }
        public override string Scheme
        {
            get { return this.transport.Scheme; }
        }
    }
}

The following code illustrates how you can configure your custom binding class programmatically.

?
1
2
3
4
5
6
DDJSecureBinding bindingObject = new DDJSecureBinding();
bindingObject.Elements.Add(new BinaryMessageEncodingBindingElement());
bindingObject.Elements.Add(new HttpTransportBindingElement());
ServiceHost host = new ServiceHost(typeof(DDJService));
ServiceEndpoint serviceEndpoint = host.AddServiceEndpoint(typeof(IDDJService), bindingObject, "http://localhost:1234/DDJService");
host.Open();


You can also create a custom binding element class that derives from theBindingCollectionElement abstract base class so that you can specify the custom binding using configuration. Here is how this class might look:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
namespace DDJService
{
 public class DDJSecureBindingCollectionElement
        : BindingCollectionElement
    {
        public override Type BindingType
        {
            get { return typeof(DDJSecureBinding); }
        }
        public override ReadOnlyCollection<IBindingConfigurationElement>
                              ConfiguredBindings
        {
            get
            {
                return new ReadOnlyCollection<IBindingConfigurationElement>(
                new List<IBindingConfigurationElement>());
            }
        }
        protected override Binding GetDefault()
        {
            return new DDJSecureBinding();
        }
    }
}

Here's how you can configure your service using the service configuration file:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<system.serviceModel>
    <services>
        <service name="DDJService">
            <endpoint address="net.tcp://localhost:1234/IDDJService"
            binding="DDJSecureBinding"
            contract="IDDJService">
            </endpoint>
        </service>
    </services>
    <extensions>
        <bindingExtensions>
            <add name="DDJSecureBinding"
               type="DDJService.DDJSecureBindingCollectionElement,
               CustomBinding,
               Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        </bindingExtensions>
    </extensions>
</system.serviceModel>


You can also leverage the CustomBinding class of theSystem.ServiceModel.Channels.Binding namespace to create custom binding for your service:


?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using (ServiceHost serviceHost = new ServiceHost (typeof(DDJService), serviceAddress))
{
    ReliableSessionBindingElement reliableSession = new ReliableSessionBindingElement();
    reliableSession.Ordered = true;
    HttpTransportBindingElement httpTransportBindingElement = new HttpTransportBindingElement();
    httpTransportBindingElement.AuthenticationScheme = System.Net.AuthenticationSchemes.Anonymous;
    httpTransportBindingElement.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
    CustomBinding bindingObject = new CustomBinding(reliableSession, httpTransportBindingElement);
    serviceHost.AddServiceEndpoint(typeof(IDDJService), bindingObject, String.Empty);
    ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior();
    serviceMetadataBehavior.HttpGetEnabled = true;
    serviceMetadataBehavior.HttpGetUrl = new Uri("http://localhost:1234/DDJService");
    serviceHost.Description.Behaviors.Add(serviceMetadataBehavior);
    serviceHost.Open();
}

The following code snippet illustrates how you can implement your own custom binding class by deriving from the System.ServiceModel.Channels.CustomBinding class:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class DDJCustomHttpBinding : CustomBinding
   {
       private readonly Boolean IsHttpsEnabled;
       private readonly Boolean IsBinaryEncodingEnabled;
       private readonly HttpTransportBindingElement transport;
       public DDJCustomHttpBinding(Boolean isHttpsEnabled, Boolean isBinaryEncodingEnabled = true)
       {
           this.IsHttpsEnabled = isHttpsEnabled;
           transport = IsHttpsEnabled ? new HttpsTransportBindingElement() : new HttpTransportBindingElement();
           IsBinaryEncodingEnabled = isBinaryEncodingEnabled;
       }      
       public override BindingElementCollection CreateBindingElements()
       {
           BindingElement security;
           if (IsHttpsEnabled)
           {
               security = SecurityBindingElement.CreateSecureConversationBindingElement(
                   SecurityBindingElement.CreateUserNameOverTransportBindingElement());
           }
           else
           {
               security = SecurityBindingElement.CreateSecureConversationBindingElement(
                   SecurityBindingElement.CreateUserNameForSslBindingElement(true));
           }
           MessageEncodingBindingElement encodingObject;
               encodingObject = IsBinaryEncodingEnabled
                           ? (MessageEncodingBindingElement)new BinaryMessageEncodingBindingElement()
                           : new TextMessageEncodingBindingElement();
           return new BindingElementCollection(new[]
           {
               security,
               encoding,
               transport,
           });
       }
       public long MaxMessageSize
       {
           set
           {
               transport.MaxReceivedMessageSize = value;
               transport.MaxBufferSize = (int)value;
           }
       }
   }