Saturday, 17 January 2015

WCF Binding



Binding will describes how client will communicate with service. There are different protocols available for the WCF to communicate to the Client. You can mention the protocol type based on your requirements.
Binding has several characteristics, including the following:
1)    Transport: Defines the base protocol to be used like HTTP, Named Pipes, TCP, and MSMQ are some type of protocols.
2)    Encoding (Optional): Three types of encoding are available - Text, Binary, and MTOM (Message Transmission Optimization Mechanism). MTOM is an interoperable message format that allows the effective transmission of attachments or large messages (greater than 64K).
3)    Protocol (Optional): Defines information to be used in the binding such as security, transaction or reliable messaging capability.

Bindings and Channel Stacks
In WCF all the communication details are handled by channel, it is a stack of channel components that all messages pass through during runtime processing. The bottom-most component is the transport channel. This implements the given transport protocol and reads incoming messages off the wire. The transport channel uses a message encoder to read the incoming bytes into a logical Message object for further processing.

After that, the message bubbles up through the rest of the channel stack, giving each protocol channel an opportunity to do its processing, until it eventually reaches the top and WCF dispatches the final message to your service implementation. Messages undergo significant transformation along the way.
It is very difficult for the developer to work directly with channel stack architecture, because you have to be very careful while ordering the channel stack components, and whether or not they are compatible with one other.
So WCF provides easy way of achieving this using end point. In end point we will specify address, binding and contract. To know more about end point, Windows Communication Foundation follows the instructions outlined by the binding description to create each channel stack. The binding binds your service implementation to the wire through the channel stack in the middle.


Types of Binding
Let us see more detailed on predefined binding:

BasicHttpBinding

·         It is suitable for communicating with ASP.NET Web services (ASMX)-based services that comfort with WS-Basic Profile conformant Web services.
·         This binding uses HTTP as the transport and text/XML as the default message encoding.
·         Security is disabled by default.
·         This binding does not support WS-* functionalities like WS- Addressing, WS-Security, WS-ReliableMessaging.
·         It is fairly weak on interoperability.

 

WSHttpBinding

·         Defines a secure, reliable, interoperable binding suitable for non-duplex service contracts.
·         It offers lot more functionality in the area of interoperability.
·         It supports WS-* functionality and distributed transactions with reliable and secure sessions using SOAP security.
·         It uses HTTP and HTTPS transport for communication.
·         Reliable sessions are disabled by default.

 

WSDualHttpBinding

·         This binding is same as that of WSHttpBinding, except it supports duplex service. Duplex service is a service which uses duplex message pattern, which allows service to communicate with client via callback.
·         In WSDualHttpBinding reliable sessions are enabled by default. It also supports communication via SOAP intermediaries.

 

WSFederationHttpBinding

·         This binding support federated security. It helps implementing federation which is the ability to flow and share identities across multiple enterprises or trust domains for authentication and authorization. It supports WS-Federation protocol.

 

NetTcpBinding

·         This binding provides secure and reliable binding environment for .Net to .Net cross machine communication. By default it creates communication stack using WS-ReliableMessaging protocol for reliability, TCP for message delivery and windows security for message and authentication at run time. It uses TCP protocol and provides support for security, transaction and reliability.

NetNamedPipeBinding

·         This binding provides secure and reliable binding environment for on-machine cross process communication. It uses NamedPipe protocol and provides full support for SOAP security, transaction and reliability. By default it creates communication stack with WS-ReliableMessaging for reliability, transport security for transfer security, named pipes for message delivery and binary encoding.

NetMsmqBinding

·         This binding provides secure and reliable queued communication for cross-machine environment.
·         Queuing is provided by using MSMQ as transport.
·         It enables for disconnected operations, failure isolation and load leveling.

NetPeerTcpBinding

·         This binding provides secure binding for peer-to-peer environment and network applications.
·         It uses TCP protocol for communication.
·         It provides full support for SOAP security, transaction and reliability.


Binding configuration

Binding can be configured either through configuration file or Programming. Let us see the binding representation in each method.

Administrative (Configuration file):

In the configuration file of the hosting application, you can add the <bindings> element inside the <system.serviceModel> element and add the properties to particular binding type. Properties corresponding to the particular binding type can be mentioned below. Name of the binding properties that you are going to use has to be mention in the end point.
<system.serviceModel>
  <services>
   <service name="MyService">
        <endpoint address="http://localhost/IISHostedService/MyService.svc" 
               binding="wsHttpBinding" bindingName="wshttpbind" 
               contract="IMyService">
            <identity>
                 <dns value="localhost"/>
            </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" 
               contract="IMetadataExchange"/>
    </service>
  </services>
  <bindings>
      <wsHttpBinding>
        <binding name="wshttpbind" allowCookies="true" closeTimeout="00:01:00" receiveTimeout="00:01:00" />
      </wsHttpBinding>
  </bindings>
</system.serviceModel>

 

Programming Model:

In the following code, I have created the WSHttpBinding object and assign the properties which to be configured. This binding object is added to the Service endpoint for client communication. Similarly you can also create any type of binding and add to endpoint.
//Create a URI to serve as the base address
Uri httpUrl = new Uri("http://localhost:8090/MyService/SimpleCalculator");
 
//Create ServiceHost
ServiceHost host = new ServiceHost(typeof(MyCalculatorService.SimpleCalculator), httpUrl);
 
//Create Binding to add to end point
WSHttpBinding wshttpbind = new WSHttpBinding();
wshttpbind.AllowCookies = true;
wshttpbind.CloseTimeout = new TimeSpan(0, 1, 0);
wshttpbind.ReceiveTimeout = new TimeSpan(0, 1, 0);
 
//Add a service endpoint
host.AddServiceEndpoint
 (typeof(MyCalculatorService.ISimpleCalculator), wshttpbind, "");
 
//Enable metadata exchange
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
 
//Start the Service
host.Open();
 
Console.WriteLine("Service is host at " + DateTime.Now.ToString());
Console.WriteLine("Host is running... Press key to stop");
Console.ReadLine();
 
Note: It is always good if you configure the binding properties using configuration file, because while moving to the production you no need to change in the code and recompile it. It is always good practice to represent in the configuration file.

 

 

Metadata Exchange

WCF provides rich infrastructure for Exporting, Publishing, retrieving and Importing the metadata. WCF uses the Metadata to describe how to interact with the service endpoint. Using the metadata, client will create the proxy class for the service using SvcUtil.exe.

Exporting Service Metadata:

It is the process of describing the service endpoint so that client can understand how to use the service.

Publishing Service Metadata:

It is the process publishing metadata. It involves converting CLR type and binding information into WSDL or some other low level representation.

Retrieving Service Metadata:

It is the process of retrieving the metadata. It uses WS-MetadataExcahge or HTTP protocol for retrieving the metadata.
Importing Service Metadata:
It is the process of generating the abstract representation of the service using metadata.
Now we are going to focus mainly on publishing metadata. There are two way to publish metadata, either we can use HTTP-GET or through message exchange endpoint. By default service metadata is turn-off due to security reason. WCF metadata infrastructure resides in System.ServiceModel.Description namespace. Service metadata can be used for following purpose:
·         Automatically generating the client for consuming service.
·         Implementing the service description.
  • Updating the binding for a client.
Now let us understand the publishing the metadata using HTTP-GET method.

 

 

HTTP_GET Enabled Metadata

We will use ServiceBehaviour to publish the metadata using HTTP-GET. This can be configures either administratively or programmatically. Http and Https can expose by appending "?wsdl" to the end of the service address. For example service address is http://localhost:9090/MyCalulatorService, HTTP-Get metadata address is given by http://localhost:9090/MyCalulatorService?wsdl.

Administrative (Configuration file):

In the below mention configuration information, you can find the behavior section in the ServiceBehavior. You can expose the metadata using ServiceMetadata node with httpGetEnabled='True'.
<system.serviceModel>
   <services>
        <service behaviorConfiguration="ServiceBehavior" name="MyService">
           <endpoint address="http://localhost/IISHostedService/MyService.svc"
            binding="wsHttpBinding" contract="IMyService">
               <identity>
                       <dns value="localhost"/>
               </identity>
            </endpoint>
        </service>
  </services>
  <behaviors>
    <serviceBehaviors>
        <behavior name="ServiceBehavior">
                <!-Setting httpGetEnabled you can publish the metadata -->
               <serviceMetadata httpGetEnabled="true"/>
               </behavior>
            </serviceBehaviors>
   </behaviors>
</system.serviceModel>

 

Programming Model:

Using ServiceMetadataBehavior you can enable the metadata exchange. In the following code, I have created the ServiceMetadataBehavior object and assigned HttpGetEnabled property to true. Then you have to add the behavior to host description as shown. This set of code will publish the metadata using HTTP-GET.
//Create a URI to serve as the base address
Uri httpUrl = new Uri("http://localhost:8090/MyService/SimpleCalculator");
 
//Create ServiceHost
ServiceHost host = new 
ServiceHost(typeof(MyCalculatorService.SimpleCalculator), httpUrl);
 
//Add a service endpoint
host.AddServiceEndpoint           (typeof(MyCalculatorService.ISimpleCalculator), new WSHttpBinding(), "");
 
//Enable metadata exchange
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
 
//Enable metadata exchange using HTTP-GET
smb.HttpGetEnabled = true;
 
host.Description.Behaviors.Add(smb);
 
//Start the Service
host.Open();
Console.WriteLine("Service is host at " + DateTime.Now.ToString());
Console.WriteLine("Host is running... Press key to stop");
Console.ReadLine();


Metadata Exchange Endpoint

Exposing the metadata using HTTP-GET has a disadvantage, such that there is no guarantee that other platforms you interact will support it. There is other way of exposing the using special endpoint is called as Metadata Exchange Endpoint. You can have as many metadata exchange endpoints as you want.

Address: It is basically Uri to identify the metadata. You can specify as address in the endpoint but append with "mex" keyword. For example http://localhost:9090/MyCalulatorService/mex

Binding: There are four types of bindings supported for metadata exchange. They are mexHttpBinding, mexHttpsBinding, mexNamedPipesBinding, mexTcpBinding.

Contract: IMetadataExchange is the contract used for MEX endpoint. WCF service host automatically provides the implementation for this IMetadataExcahnge while hosting the service.

You can create the Metadata Exchange Endpoint either Administrative (configuration file) or programmatically.

Administrative (Configuration file):

In the configuration file of the hosting application, you can add metadata exchange endpoint as shown below.
<system.serviceModel>
<services>
        <service name="MyService">
        <endpoint address="http://localhost/IISHostedService/MyService.svc"
                binding="wsHttpBinding" contract="IMyService">
        <identity>
                <dns value="localhost"/>
        </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" 
               contract="IMetadataExchange"/>
        </service>
</services>            
</system.serviceModel>

 

Programming Model:

In the following code I have mention about creating the Metadata Exchange Endpoint through coding. Steps to create the metadata endpoint are:
·         Create the ServiceMetadataBehavior object and add to Service host description.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
host.Description.Behaviors.Add(smb);

·         Create the metadata binding object using MetadataExchangeBinding.
Binding mexBinding = MetadataExchangeBindings.CreateMexHttpBinding ();

·         Add the endpoint to the service host with address, binding and contract.
host.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "mex");
Complete code for hosting the service with metadata exchange endpoint is shown below.
//Create a URI to serve as the base address
Uri httpUrl = new Uri("http://localhost:8090/MyService/SimpleCalculator");
 
//Create ServiceHost
ServiceHost host = new 
ServiceHost(typeof(MyCalculatorService.SimpleCalculator), httpUrl);
 
//Add a service endpoint
host.AddServiceEndpoint
 (typeof(MyCalculatorService.ISimpleCalculator), new WSHttpBinding(), "");
 
//Enable metadata exchange
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
host.Description.Behaviors.Add(smb);
Binding mexBinding = MetadataExchangeBindings.CreateMexHttpBinding ();
 
//Adding metadata exchange endpoint
host.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "mex");
 
//Start the Service
host.Open();
 
Console.WriteLine("Service is host at " + DateTime.Now.ToString());
Console.WriteLine("Host is running... Press key to stop");
Console.ReadLine();
 
 
 

No comments:

Post a Comment