Introduction
In this article we will see how to create a service contract base class in C# 5.0. We will discuss the supported bindings in WCF and show how to design and implement your own custom binding class with additional protocols, security and so on for use in WCF 4.5. (To work with the code examples discussed in this article, you should use Visual Studio 2012 or later.)
Service contracts in WCF
Service contracts in WCF are used to expose one or more operations. We can define the operations by creating a method and then use the OperationContractAttribute attribute to expose it. Note that methods that are not decorated with this attribute are not service operations (meaning they are not exposed by your WCF service). While you can use either an interface or a class to design your service contract, using an interface has several advantages.
The following code illustrates an interface-based service contract:
- [ServiceContract]
- public interface ITestService
- {
- [OperationContractAttribute]
- public string GetSomeData();
- [OperationContractAttribute]
- public void StoreSomeData();
- }
Bindings in WCF 4.5
Address, Binding, and Contract are commonly referred to as the "ABCs" of WCF. An Address specifies the absolute or relative path or the Uniform Resource Indicator (URI) of the service. In WCF, Binding is used to specify the transport channel that your service uses. Contract specifies 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
BasicHttpBinding
BasicHttpBinding is the simplest type of binding used. It provides support for both the HTTP and HTTPS protocol. The following code snippet illustrates how this type of binding can be specified.
- <bindings>
- <basicHttpBinding>
- <binding name="CCRServiceBinding">
- <security mode="Transport">
- <transport clientCredentialType="None"/>
- </security>
- </binding>
- </basicHttpBinding>
- </bindings>
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.
- <binding name=" CCRServiceBinding ">
- <security mode="TransportWithMessageCredential">
- <transport clientCredentialType="None"/>
- <message clientCredentialType="IssuedToken"/>
- </security>
- </binding>
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.
- <client>
- <endpoint name="Sample" address="net.tcp://localhost:1234/CCRService"
- binding="netTcpBinding" contract="ICCRService" >
- <identity>
- <servicePrincipalName value=”CCRService/RamaSagar-PC” />
- </identity>
- </endpoint>
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 to specify this type of binding for your service:
- <services>
- <service name="CCRService" behaviorConfiguration="CCRService Behavior">
- <host>
- <baseAddresses>
- <add baseAddress="net.pipe://localhost:1234/CCRService "/>
- </baseAddresses>
- </host>
- <endpoint address="" binding="netNamedPipeBinding" contract="ICCRService "></endpoint>
- </service>
- </services>
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 to configure this type of binding.
- <endpoint
- address="net.p2p://localhost:1234/CCRService/"
- binding="netPeerTcpBinding"
- bindingConfiguration="netp2pBinding"
- contract="ICCRService">
- <bindings>
- <netPeerTcpBinding>
- <binding name="netP2P" >
- <resolver mode="Pnrp" />
- <security mode="None" />
- </binding>
- </netPeerTcpBinding>
- </bindings>
If you need support for the Duplex Message Exchange (where services can communicate with their clients through callbacks), you need to use WsDualHttpBinding. In essence, it is WsHttpBinding with support for a Duplex Message Exchange pattern.
WsFederationHttpBinding
In WCF, WsFederationHttpBinding is used for federated security.
CustomBinding
We can implement your own custom binding class for additional transport protocols, security and so on. To implement a custom binding class, you need to derive a class from the System.ServiceModel.Channels.Binding class.
- using System.ServiceModel.Channels;
- namespace CCRService
- {
- public class CCRSecureBinding : 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; }
- }
- }
- }
- CCRSecureBinding bindingObject = new CCRSecureBinding();
- bindingObject.Elements.Add(new BinaryMessageEncodingBindingElement());
- bindingObject.Elements.Add(new HttpTransportBindingElement());
- ServiceHost host = new ServiceHost(typeof(CCRService));
- ServiceEndpoint serviceEndpoint = host.AddServiceEndpoint(typeof(ICCRService), bindingObject, "http://localhost:1234/CCRService");
- host.Open();
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.ServiceModel.Channels;
- using System.ServiceModel.Configuration;
- namespace CCRService
- {
- public class CCRSecureBindingCollectionElement
- : BindingCollectionElement
- {
- public override Type BindingType
- {
- get { return typeof(CCRSecureBinding); }
- }
- public override ReadOnlyCollection<IBindingConfigurationElement>
- ConfiguredBindings
- {
- get
- {
- return new ReadOnlyCollection<IBindingConfigurationElement>(
- new List<IBindingConfigurationElement>());
- }
- }
- protected override Binding GetDefault()
- {
- return new CCRSecureBinding();
- }
- }
- }
- <system.serviceModel>
- <services>
- <service name="CCRService">
- <endpoint address="net.tcp://localhost:1234/ICCRService"
- binding="CCRSecureBinding"
- contract="ICCRService">
- </endpoint>
- </service>
- </services>
- <extensions>
- <bindingExtensions>
- <add name="CCRSecureBinding"
- type="CCRService.CCRSecureBindingCollectionElement,
- CustomBinding,
- Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
- </bindingExtensions>
- </extensions>
- </system.serviceModel>
- using (ServiceHost serviceHost = new ServiceHost (typeof(CCRService), 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(ICCRService), bindingObject, String.Empty);
- ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior();
- serviceMetadataBehavior.HttpGetEnabled = true;
- serviceMetadataBehavior.HttpGetUrl = new Uri("http://localhost:1234/CCRService");
- serviceHost.Description.Behaviors.Add(serviceMetadataBehavior);
- serviceHost.Open();
- }
- public class CCRCustomHttpBinding : CustomBinding
- {
- private readonly Boolean IsHttpsEnabled;
- private readonly Boolean IsBinaryEncodingEnabled;
- private readonly HttpTransportBindingElement transport;
- public CCRCustomHttpBinding(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;
- }
- }
- }
In this article we saw the advanced service contract features of WCF 4.5 (as well as the various types of bindings) and implemented a sample custom binding class. We can easily add more features and customization to WCF's binding framework.

Ramasagar PulidindiPosted Jun 12, 2014, 12:16 AM
Thank you sir
Former memberPosted Jun 11, 2014, 7:48 PM
Nice article