Saturday, 15 June 2013

Complete - WCF

WCF Tutorial


Activation and Hosting:
WCF service can be hosted by following mechanism

IIS: It does not require Host code to activate the service, it automatically activates service code. It will automatically launch the host service when it gets first request from the client. The disadvantage is that it will support only HTTP.

Windows Activation Service: (WAS) is the new process activation mechanism that ships with IIS 7.0. It is available with IIS 7.0 and it is more powerful compared to IIS 6.0 because it supports Http, TCP and named pipes where IIS 6.0 supports only Http. It can be installed and configured separately.

Hosting WCF in Activation service takes many advantages such as process recycling, isolation, idle time management and common configuration system. WAS hosted service can be created using following steps
-Enable WCF for non-http protocols
-Create WAS hosted service
-Enable different binding to the hosted service

Self-Hosting: WCF service can be self hosted as console application, Win Forms or WPF application with graphical UI.

ServiceHost is the core class use to host the WCF service. It will accept implemented contract class and base address as contractor parameter. You can register multiple base addresses separated by commas, but address should not use same transport schema.

Windows Service: WCF can also be hosted as a Windows Service, so that it is under control of the Service Control Manager (SCM).
advantage of hosting service in Windows service:
-The service will be hosted, when system starts
-Process life time of the service can be controlled by Service Control Manager for windows service
-All versions of Windows will support hosting WCF service.

There are different ways of creating the proxy:
-Using SvcUtil.exe, we can create the proxy class and configuration file with end points.
-Adding Service reference to the client application.
-Implementing ClientBase<T> class : it will create the proxy only at runtime.

WCF:
WCF is a combined features of Web Service, Remoting, MSMQ and COM+. WCF provides a common platform for all .NET communication.
Advantage:
-WCF is interoperable with other services when compared to .Net Remoting,where the client and service have to be .Net.
-WCF services provide better reliability and security in compared to ASMX web services.
-In WCF, there is no need to make much change in code for implementing the security model and changing the binding. Small changes in the configuration will make your requirements.
-WCF has integrated logging mechanism, changing the configuration file settings will provide this functionality. In other technology developer has to write the code.

WCF services can be debugged now in Visual Studio 2008. Wcfsvchost.exe will do it for you because service will be self hosted when you start debugging.

Difference between Web Service and WCF:
Features -- Web Service -- WCF :

Hosting:
It can be hosted in IIS It
can be hosted in IIS, windows activation service, Self-hosting, Windows service
Programming:
[WebService] attribute has to be added to the class
[ServiceContraact] attribute has to be added to the class
Model:
[WebMethod] attribute represents the method exposed to client
[OperationContract] attribute represents the method exposed to client
Operation:
One-way, Request- Response are the different operations supported in web service
one-Way, Request-Response, Duplex are different type of operations supported in WCF
XML:
System.Xml.serialization name space is used for serialization
System.Runtime.Serialization namespace is used for serialization
Encoding:
XML 1.0, MTOM(Message Transmission Optimization Mechanism), DIME, Custom
XML 1.0, MTOM, Binary, Custom
Transports:
Can be accessed through HTTP, TCP, Custom
Can be accessed through HTTP, TCP, Named pipes, MSMQ,P2P, Custom
Protocols:
Security
Security, Reliable messaging, Transactions

A service is a class that exposes functionality available to clients at one or more endpoints. To create a service, write a class that implements a WCF contract. You can do this in one of 2 ways.
You can define the contract separately as an interface and then create a class that implements that interface.

// Define the IMath contract.
[ServiceContract]
public interface IMath
{
[OperationContract]
double Add(double A, double B);
[OperationContract]
double Multiply (double A, double B);
}
// Implement the IMath contract in the MathService class.
public class MathService : IMath
{
public double Add (double A, double B) { return A + B; }
public double Multiply (double A, double B) { return A * B; }

Alternatively, you can create the class and contract directly by placing the ServiceContractAttribute attribute on the class

itself and the OperationContractAttribute attribute on the methods available to the clients of the service.

// Define the MathService contract directly on the service class.
[ServiceContract]class MathService
{
[OperationContract] public double Add(double A, double B) { return A + B; }
[OperationContract]
private double Multiply (double A, double B) { return A * B; }
}
WCF is an SDK for developing and deploying services on Windows. WCF provides a runtime environment for your services, enabling you to expose CLR types as services, and to consume other services as CLR types.
WCF provides interoperability between services.
Most all of the WCF functionality is included in a single assembly called System.ServiceModel.dll in the System.ServiceModel namespace.

The basic tasks to perform are, in order:
1. Define the service contract.A service contract specifies the signature of a service, the data it exchanges, and other contractually required data.
2. To implement a service contract, create the class that implements the contract and specify custom behaviors that the runtime should have.
3. Configure the service by specifying endpoint information and other behavior information.
4. Host the service in an application.
5. Build a client application.

With WCF, all messages are SOAP messages. The messages are independent of transport protocols unlike Web services, WCF services may communicate over a variety of transports, not just HTTP. WCF clients may interoperate with non-WCF services, and
WCF services can interact with non-WCF clients.

With WCF, the client never interacts with the service directly. Instead, the client always uses a proxy to forward the call to the service. The proxy exposes the same operations as the service, plus some proxy-management methods.

WCF allows the client to communicate with the service across all execution boundaries. On the same machine, the client can consume services in the same app domain, across app domains in the same process, or across processes.

It is possible for two TCP addresses (from the same host) to share a port:
net.tcp://localhost:8002/MyService
net.tcp://localhost:8002/MyOtherService
Similar to TCP addresses, two HTTP addresses from the same host can share a port, even on the same machine.

IPC addresses use net.pipe for transport, to indicate the use of the Windows named pipe mechanism.
net.pipe://localhost/MyPipe
You can only open a named pipe once per machine, and therefore it is not possible for two named pipe addresses to share a pipe name on the same machine.

MSMQ addresses use net.msmq for transport, to indicate the use of the Microsoft Message Queue (MSMQ). You must specify the queue name. When you're dealing with private queues, you must specify the queue type, but that can be omitted for public queues:
net.msmq://localhost/private/MyService
net.msmq://localhost/MyService

WCF defines 4 types of contracts.
1. Service contracts: Describe which operations the client can perform on the service.
2. Data contracts: Define which data types are passed to and from the service. Data Contract attribute defines the data type that will be exchanged between the client and the service.
3. Fault contracts: Define which errors are raised by the service, and how the service handles and propagates errors to its clients.
4. Message contracts: Allow the service to interact directly with messages. Message contracts can be typed or untyped, and are useful in interoperability cases and when there is an existing message format you have to comply with.



WCF Hosting:
WCF service cannot exist on its own; it has to be hosted in windows process called as host process. Single host process can host multiple servers and same service type can be hosted in multiple host process. There are mainly 4 different way of hosting the WCF service.
-IIS hosting
-Self hosting
-Windows Activation Service
-Windows Service

Hosting Environment Supported protocol
Windows console and form application -HTTP,net.tcp,net.pipe,net.msmq
Windows service application -HTTP,net.tcp,net.pipe,net.msmq
Web server IIS6 -http, wshttp
Web server IIS7 - WAS, HTTP, net.tcp, net.pipe, net.msmq

A summary of hosting options and supported features.

Feature                                   Self-Hosting   IIS Hosting    WAS Hosting
Executable Process/ App Domain      Yes            Yes               Yes
Configuration                             App.config    Web.config     Web.config
Activation                            Manual at startup Message-based Message-based
Idle-Time Management                   No                   Yes            Yes
Health Monitoring                          No                  Yes             Yes
Process Recycling                         No                 Yes                Yes
Management Tools                       No                    Yes              Yes

IIS Hosting:
The main advantage of hosting a service in IIS web server is that the host process is launched automatically upon the first client request, and you rely on IIS to manage the life cycle of the host process. It uses the features of IIS such as process recycling, idle shutdown, process health monitoring and message based activation. The main disadvantage of IIS hosting is that it will support only HTTP protocol. With IIS5, you are further restricted to having all services use the same port number.

Example 1-2. A .svc file
<%@ ServiceHost
Language = "C#"
Debug = "true"
CodeBehind = "~/App_Code/MyService.cs"
Service = "MyService"
%>

When configuring a service in Visual Studio, use either a Web.config or an App.config file to specify the settings.
If you are using IIS to host your service, use a Web.config file. If you are using any other hosting environment, use an App.config file.

SELF Hosting: WCF provides the user to host the service in any application (e.g. console application, Windows form).
WAS Hosting:
WAS is a system service available with Windows Vista and Windows Server 2008. WAS is part of IIS7, but can be installed and configured separately. To use the WAS for hosting your WCF service, you need to supply a .svc file, just as with IIS.
The main difference between IIS and WAS is that the WAS is not limited to HTTP and can be used with any of the available WCF transports, ports, and queues.

WAS offers advantages over self-hosting, including application pooling, process recycling, idle time management, identity management, and isolation, and is the host process of choice when available; that is, when you can target either a Vista Server machine for scalability or a Vista client machine used as a server machine for a handful of clients only.

WAS hosted service can be created using following steps:
-Enable WCF for non-http protocols
-Create WAS hosted service
-Enable different binding to the hosted service

Service Host
Service Host object is in the process of hosting the WCF service and registering endpoints. It loads the service configuration endpoints, apply the settings and start the listeners to handle the incoming request.

System.ServiceModel.ServiceHost namespace hold this object. This object is created while self hosting the WCF service.

In the below example you can find that WCF service is self hosted using console application.

//Creating uri for the hosting the service
Uri uri = new Uri("http://localhost/CategoryService");
//Creating the host object for MathService
ServiceHost host = new ServiceHost(typeof(CategoryService), uri);
//Adding endpoint to the Host object
host.AddServiceEndpoint(typeof(ICategoryService),new WSHttpBinding(), uri);
host.Open(); //Hosting the Service
Console.WriteLine("Waiting for client invocations");
Console.ReadLine();
host.Close();

EndPoint:
Each endpoint consists of four properties:
-An address that indicates where the endpoint can be found.
-A binding that specifies how a client can communicate with the endpoint.
-A contract that identifies the operations available.
-A set of behaviors that specify local implementation details of the endpoint.

Address:
Every endpoint must have a unique address. The endpoint address is represented by the EndpointAddress class, which contains a Uniform Resource Identifier (URI) that represents the address of the service, an Identity, which represents the security identity of the service, and a collection of optional Headers. The optional headers provide more detailed addressing information to identify or interact with the endpoint. For example, headers can indicate how to process an incoming message, where the endpoint should send a reply message, or which instance of a service to use to process an incoming message from a
particular user when multiple instances are available.

Binding:
The binding specifies how to communicate with the endpoint. This includes:
-The transport protocol to use ( TCP or HTTP)
-The encoding to use for the messages (text or binary)
-The necessary security requirements (SSL or SOAP message security)

There are different protocols available for the WCF to communicate to the Client. You can mention the protocol type based on your requirements.

A binding has several characteristics, including the following:
Transport -Defines the base protocol to be used like HTTP, Named Pipes, TCP, and MSMQ are some type of protocols.
Encoding (Optional) - Three types of encoding are available-Text, Binary,or Message Transmission Optimization Mechanism (MTOM). MTOM is an interoperable message format that allows the effective transmission of attachments or large messages (greater than 64K).
Protocol(Optional) - Defines information to be used in the binding such as Security, transaction or reliable messaging capability

A binding is represented in the WCF object model by the abstract base class Binding.

BasicHttpBinding - Basic Web service communication. No security by default
WSHttpBinding - Web services with WS-* support. Supports transactions
WSDualHttpBinding - Web services with duplex contract and transaction support
WSFederationHttpBinding - Web services with federated security. Supports transactions
MsmqIntegrationBinding - Communication directly with MSMQ applications. Supports transactions
NetMsmqBinding - Communication between WCF applications by using queuing. Supports transactions
NetNamedPipeBinding - Communication between WCF applications on same computer. Supports duplex contracts and transactions
NetPeerTcpBinding - Communication between computers across peer-to-peer services. Supports duplex contracts
NetTcpBinding - Communication between WCF applications across computers. Supports duplex contracts and transactions

Basic binding: Offered by the BasicHttpBinding class, this is designed to expose a WCF service as a legacy ASMX web service, so that old clients can work with new services. When used by the client, this binding enables new WCF clients to work with old ASMX services. An HTTP protocol binding suitable for connecting to Web services that conforms to the WS-I Basic Profile specification (for example, ASP.NET Web services-based services).
TCP binding:
Offered by the NetTcpBinding class, this uses TCP for cross-machine communication on the intranet. It supports a variety of features, including reliability, transactions, and security, and is optimized for WCF-to-WCF communication. As a result, it requires both the client and the service to use WCF.
Peer network binding:
Offered by the NetPeerTcpBinding class, this uses peer networking as a transport.
IPC binding:Offered by the NetNamedPipeBinding class, this uses named pipes as a transport for same-machine communication. It is the most secure binding since it cannot accept calls from outside the machine and it supports a variety of features
similar to the TCP binding.
Web Service (WS) binding:
Offered by the WSHttpBinding class, this uses HTTP or HTTPS for transport, and is designed to offer a variety of features such as reliability, transactions, and security over the Internet.
An interoperable binding suitable for connecting to endpoints that conform to the WS-* protocols.

Federated WS binding:
Offered by the WSFederationHttpBinding class, this is a specialization of the WS binding
MSMQ binding:Offered by the NetMsmqBinding class, this uses MSMQ for transport and is designed to offer support for disconnected queued calls.
MSMQ integration binding:
Offered by the MsmqIntegrationBinding class, this converts WCF messages to and from MSMQ messages,

NetMsmqBinding:
Uses the .NET Framework to create queued message connections with other WCF endpoints.

Name                                 Transport            Encoding           Interoperable
asicHttpBinding                 HTTP/HTTPS Text, MTOM                    Yes
NetTcpBinding                    TCP                     Binary                     No
NetPeerTcpBinding                P2P                    Binary                   No
NetNamedPipeBinding             IPC                    Binary                  No
WSHttpBinding HTTP/HTTPS Text, MTOM Yes
WSFederationHttpBinding HTTP/HTTPS Text, MTOM Yes
WSDualHttpBinding               HTTP Text,            MTOM               Yes
NetMsmqBinding                      MSMQ              Binary                      No
MsmqIntegrationBinding            MSMQ               Binary                       Yes

Binding                        Configuration Element                         Description

BasicHttpBinding <basicHttpBinding>           A binding that is suitable for communicating with WS-Basic Profile conformant Web services, for example, ASP.NET Web services (ASMX)-based services. This binding uses HTTP as the transport and text/XML as the default message encoding.

WSHttpBinding    <wsHttpBinding>              A secure and interoperable binding that is suitable for non-duplex service contracts.

NetTcpBinding    <netTcpBinding>              A secure and optimized binding suitable for cross-machine communication between WCF applications.

NetPeerTcpBinding <netPeerTcpBinding>      A binding that enables secure, multiple machine communication.
MsmqIntegrationBinding <msmqIntegrationBinding> A binding that is suitable for cross-machine communication between a WCF application and existing Message Queuing applications.

WSDualHttpBinding <wsDualHttpBinding>      A secure and interoperable binding that is suitable for duplex service contracts or communication through SOAP intermediaries.

Contracts:
What operations can be called by a client.
The form of the message.
The type of input parameters or data required to call the operation.
What type of processing or response message the client can expect.

service contract is a statement that provides information about:
-The grouping of operations in a service.
-The signature of the operations in terms of messages exchanged.
-The data types of these messages.
-The location of the operations.
-The specific protocols and serialization formats that are used to support successful communication with the service.

A duplex contract consists of two interfaces.
-The primary interface is used to send messages from client to service.
-The callback interface is used to send messages from service back to client.

A duplex contract allows clients and servers to communicate with each other independently so that either can initiate calls to the other. The duplex contract is one of 3 message patterns available to WCF services. The other two message patterns are one-way and request-reply.
A duplex contract consists of two one-way contracts between the client and the server and does not require that the method calls be correlated. Use this kind of contract when your service must query the client for more information or explicitly raise events on the client.

sample program: http://msdn.microsoft.com/en-us/library/ms731184(v=VS.100).aspx

Use the ServiceModel Metadata Utility Tool (Svcutil.exe) to retrieve the WSDL document and (optional) code and configuration for a client.
IIS bindings provide two pieces of information: a binding protocol, and binding information.
The binding protocol defines the scheme over which communication occurs, and binding information is the information used to access the site.

The following example shows the components that can be present in an IIS binding:
Binding protocol: HTTP
binding Information: IP Address, Port, Host header

IIS can specify multiple bindings for each site, which results in multiple base addresses for each scheme. Prior to .NET Framework 3.5, WCF did not support multiple addresses for a schema
With .NET Framework 3.5, you specify a prefix filter at the AppDomain level in the configuration file. You do this with the <baseAddressPrefixFilters> element, which contains a list of prefixes. The incoming base addresses, supplied by IIS, are filtered based on the optional prefix list. By default, when a prefix is not specified, all addresses are passed through.

Specifying the prefix results in only the matching base address for that scheme to be passed through.

The following is an example of configuration code that uses the prefix filters.
<system.serviceModel>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="net.tcp://payroll.myorg.com:8000"/>
<add prefix="http://shipping.myorg.com:8000"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
</system.serviceModel>

net.tcp://payroll.myorg.com:8000 and http://shipping.myorg.com:9000 are the only base addresses, for their respective schemes, which are passed through.

The baseAddressPrefixFilter does not support wildcards.

Binding and Behavior:
Binding -- how the client will communicate with service.

Consider a scenario say, I am creating a service that has to be used by two type of client. One of the client will access SOAP using http and other client will access Binary using TCP. How it can be done? With Web service it is very difficult to achieve, but in WCF its just we need to add extra endpoint in the configuration file.

<system.serviceModel>
<services>
<service name="MathService" behaviorConfiguration="MathServiceBehavior">
<endpoint address="http://localhost:8090/MyService/MathService.svc"
contract="IMathService" binding="wsHttpBinding"/>
<endpoint address="net.tcp://localhost:8080/MyService/MathService.svc"
contract="IMathService" binding="netTcpBinding"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MathServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
cording to its scope: common behaviors affect all endpoints globally, service behaviors affect only service-related aspects, endpoint behaviors affect only endpoint-related properties, and operation-level behaviors affect particular operations.

Example:
In the below configuration information, I have mentioned the Behavior at Service level. In the service behavior I have mention the servieMetadata node with attribute httGetEnabled='true'. This attribute will specifies the publication of the
service metadata. Similarly we can add more behavior to the service.

<system.serviceModel>
<services>
<service name="MathService"
behaviorConfiguration="MathServiceBehavior">
<endpoint address="" contract="IMathService"
binding="wsHttpBinding"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MathServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

Note:
Application can be controlled either through coding, configuring or through combination of both. Specification mention in the configuration can also be overwritten in code.

Binding
Binding means how the 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:
Transport-Defines the base protocol to be used like HTTP, Named Pipes, TCP, and MSMQ are some type of protocols.
Encoding (Optional)--Three types of encoding are available-Text, Binary, or Message Transmission Optimization Mechanism (MTOM). MTOM is an interoperable message format that allows the effective transmission of attachments or large messages
(greater than 64K).
Protocol(Optional)--Defines information to be used in the binding such as Security, transaction or reliable messaging capability

Message and Channel:
Message: WCF Message is the unit of data exchange between client and service. It consists of several parts, including a body and headers.

WCF Runtime: WCF runtime is the set of object responsible for sending and receiving message. For example formatting the message, applying security and transmitting and receiving message using various protocol.

Channels: Channels are the core abstraction for sending message to and receiving message from an Endpoint. Broadly we can categories channels as

Transport Channels: Handles sending and receiving message from network. Protocols like HTTP, TCP name pipes and MSMQ.

Protocol Channels: Implements SOAP based protocol by processing and possibly modifying message. e.g. WS-Security and WS-Reliability.

WCF Client and Metadata:
WCF Client:
WCF client is a client application creates to expose the service operations as method. Any application can host a WCF client, including an application that host a service. Therefore it is possible to create a service that includes WCF clients of other services.

A client application is a managed application that uses a WCF client to communicate with another application. To create a client application for a WCF service requires the following steps:

1. Get the Proxy class and service end point information:
Using SvcUtil.exe we can create proxy class for the service and configuration information for endpoints. Example type the following sentence in the Visual studio command prompt, this will generate the class file and configuration file which
contain information about the endpoints.

svcutil /language:vb /out:ClientCode.vb /config:app.config http://localhost:8090/MyService/SimpleCalculator.svc?wsdl

2. Call operations.
Add this class files in the client application. Then create the object for this class and invoke the service operation.

Configuration information we got from the above step has to be added to the client application configuration file. When the client application calls the first operation, WCF automatically opens the underlying channel. This underlying channel is
closed, when the object is recycled.

//Creating the proxy on client side
MyCalculatorServiceProxy.MyServiceProxy proxy = new MyCalculatorServiceProxy.MyServiceProxy();
Console.WriteLine("Counter: " + proxy.MyMethod());

3. Close the WCF client object.
After using the object created in the above steps, we have to dispose the object. Channel will be closed with the service, when the object is cleared.

Metadata:
Characteristics of the service are described by the metadata. This metadata can be exposed to the client to understand the
communication with service. Metadata can be set in the service by enabling the ServiceMetadata node inside the servcieBehaviour node of the service configuration file.

<system.serviceModel>
<services>
<service name="MathService" behaviorConfiguration="MathServiceBehavior">
<endpoint address="" contract="IMathService"
binding="wsHttpBinding"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MathServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

This metadata can be viewed while creating WCF client application using SvcUtil.exe
Contracts and Service Host:
Contracts
In WCF, all services are exposed as contracts. Contract is a platform-neutral and standard way of describing what the service does. WCF defines 4 types of contracts:
1. Service Contract 2. Data Contract
3. Message Contract 4. Fault Contract

1. Service Contract: Service contracts describe the operation that service can provide. For Eg, a Service provide to know the temperature of the city based on the zip code, this service is called as Service contract. It will be created using Service and Operational Contract attribute.

It describes the client-callable operations (functions) exposed by the service
It maps the interface and methods of your service to a platform-independent description

2. Data Contract: Data contract describes the custom data type which is exposed to the client. This defines the data types, that are passed to and from service. Data types like int, string are identified by the client because it is already mention in XML schema definition language document, but custom created class or data types cannot be identified by the client e.g. Employee data type. By using DataContract we can make client to be aware of Employee data type that are returning or passing parameter to the method.

A data contract is a formal agreement between a service and a client that abstractly describes the data to be exchanged.

Data contract can be explicit or implicit. Simple type such as int, string etc has an implicit data contract. User defined object are explicit or Complex type, for which you have to define a Data contract using [DataContract] and [DataMember] attribute.

A data contract can be defined as follows:
-It describes the external format of data passed to and from service operations
-It defines the structure and types of data exchanged in service messages
-It maps a CLR type to an XML Schema
-It defines how data types are serialized and deserialized. Through serialization, you convert an object into a sequence of bytes that can be transmitted over a network. Through deserialization, you reassemble an object from a sequence of bytes that
you receive from a calling application.
-It is a versioning system that allows you to manage changes to structured data

We need to include System.Runtime.Serialization reference to the project. This assembly holds the DataContract and DataMember attribute.

Create user defined data type called Employee. This data type should be identified for serialization and deserialization by mentioning with [DataContract] and [DataMember] attribute.
[ServiceContract]
public interface IEmployeeService
{
[OperationContract]
Employee GetEmployeeDetails(int EmpId);
}
[DataContract]
public class Employee
{
private string m_Name;
private int m_Age;
private int m_Salary;
private string m_Designation;
private string m_Manager;

[DataMember]
public string Name
{ get { return m_Name; }
set { m_Name = value; }
}
[DataMember]
public int Age
{
get { return m_Age; } set { m_Age = value; }
}
[DataMember]
public int Salary
{
get { return m_Salary; } set { m_Salary = value; }
}
[DataMember]
public string Designation
{
get { return m_Designation; } set { m_Designation = value; }
}
[DataMember]
public string Manager
{
get { return m_Manager; } set { m_Manager = value; }
}

}

Implementation of the service class is shown below. In GetEmployee method we have created the Employee instance and return to the client. Since we have created the data contract for the Employee class, client will aware of this instance whenever he
creates proxy for the service.

public class EmployeeService : IEmployeeService
{
public Employee GetEmployeeDetails(int empId)
{
Employee empDetail = new Employee();
//Do something to get employee details and assign to 'empDetail' properties
return empDetail;
}
}
Client side:
On client side we can create the proxy for the service and make use of it. The client side code is shown below.

protected void btnGetDetails_Click(object sender, EventArgs e)
{
EmployeeServiceClient objEmployeeClient = new EmployeeServiceClient();
Employee empDetails;
empDetails = objEmployeeClient.GetEmployeeDetails(empId);
//Do something on employee details

3. Message Contract:
Default SOAP message format is provided by the WCF runtime for communication between Client and service. If it is not meeting your requirements then we can create our own message format. This can be achieved by using Message Contract attribute.

Message is the packet of data which contains important information. WCF uses these messages to transfer information from Source to destination.

Transport Channels: Handles sending and receiving message from network. Protocols like HTTP, TCP name pipes and MSMQ.
Protocol Channels: - Implements SOAP based protocol by processing and modifying message.
e.g. WS-Security and WS-Reliability.

WCF uses SOAP Message format for communication. SOAP message contain Envelope, Header and Body.SOAP envelope contails name, namespace,header and body element. SOAP Hear contain important information which are not directly related to message. SOAP
body contains information which is used by the target.

Message Pattern: It describes how the programs will exchange message each other. There are three way of communication between source and destination
1. Simplex - It is one way communication. Source will send message to target, but target will not respond to the message.
Request/Replay - It is two way communications, when source send message to the target, it will resend response message to the source. But at a time only one can send a message
2. Duplex - It is two way communication, both source and target can send and receive message simultaniouly.

Message contract?
WCF uses SOAP message for communication. Most of the time developer will concentrate more on developing the DataContract, Serializing the data, etc. WCF will automatically take care of message. On Some critical issue, developer will also require control over the SOAP message format. In that case WCF provides Message Contract to customize the message as per requirement.

WCF supports either RPC(Remote Procedure Call) or Message style operation model. In the RPC model, you can develop operation with Ref and out parameter. WCF will automatically create the message for operation at run time. In Message style operation

WCF allows to customize the message header and define the security for header and body of the message.

Message Contract:
Message contract can be applied to type using MessageContract attribute. Custom Header and Body can be included to message using 'MessageHeader' and 'MessageBodyMember'atttribute. Let us see the sample message contract definition.

[MessageContract]
public class EmployeeDetails
{
[MessageHeader]
public string EmpID;
[MessageBodyMember]
public string Name;
[MessageBodyMember]
public string Designation;
[MessageBodyMember]
public int Salary;
[MessageBodyMember]
public string Location;
}

When I use this EmployeeDeatils type in the service operation as parameter. WCF will add extra header call 'EmpID' to the SOAP envelope. It also add Name, Designation, Salary, Location as extra member to the SOAP Body.

Rules:
-You have to follow certain rules while working with Message contract
-When using Message contract type as parameter, Only one parameter can be used in servicie Operation
[OperationContract]
void SaveEmployeeDetails(EmployeeDetails emp);

-Service operation either should return Messagecontract type or it should not return any value
[OperationContract]
EmployeeDetails GetEmployeeDetails();

-Service operation will accept and return only message contract type. Other data types are not allowed.
[OperationContract]
EmployeeDetails ModifyEmployeeDetails(EmployeeDetails emp);
Note: If a type has both Message and Data contract, service operation will accept only message contract

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.

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

1. 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 httpGetEnable='True'.
<system.serviceModel>
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
//Enable metadata exchange using HTTP-GET
host.Description.Behaviors.Add(smb);
2. Metadata Exchange Endpoint

2. Metadata Exchange Endpoint
You can create the Metadata Exchange Endpoint either Administrative (configuration file) or programmatically.
<system.serviceModel>
Programming Model:
Create the ServiceMetadataBehavior object and add to Service host description.
Create the metadata binding object using MetadataExchangeBinding
3. Add the endpoint to the service host with address, binding and contract.
Complete code for hosting the service with metadata exchange endpoint is shown below.
//Create a URI to serve as the base address
Console.WriteLine("Service is host at " + DateTime.Now.ToString());
4. Fault Contract:
WCF provides the option to handle and convey the error message to client from service using SOAP Fault contract.
Step 1: I have created simple calculator service with Add operation which will throw general exception as shown below
//Service interface
try
Define a type using the data contract and specify the fields you want to return.
Step 1:
When the client creates new proxy to particular service instance, a dedicated service instance will be provided to the client. It is independent of all other instance.
Console.WriteLine("Client 2 making call to service...");
Instance Deactivation:
ReleaseInstanceMode property of the OberationalBehavior attribute used to control the instance in relation to the method call.
List of Release modes available in the ReleaseInstanceMode:
[ServiceContract()]
Explicit Deactivate:
[ServiceContract()]
Defining the Durable Service:
CanCreateInstance = true: creats the serialization and inserting it into the datastore.
How to Create Durable Service:
[OperationContract]
using System.Runtime.Serialization;
[Serializable]
Step 4:
SqlPersistenceProviderSchema.sql
Step 5:
<system.serviceModel>
Step 7: Add following reference to client application
Step 8: Add WCF service as Service Reference to the project and name it as SimpleCalculatorService


<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>
Progarmming Model:
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();

smb.HttpGetEnabled = true;

//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();

Exposing the metadata using HTTP-GET has a disadvantage, ie 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.

Administrative (Configuration file):
In the configuration file of the hosting application, you can add metadata exchange endpoint as shown below.

<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>

Steps to create the metadata endpoint through coding are:

ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
host.Description.Behaviors.Add(smb);

Binding mexBinding = MetadataExchangeBindings.CreateMexHttpBinding ();

host.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "mex");
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("Host is running... Press key to stop");
Console.ReadLine();

Suppose the service I consumed is not working in the client application. I want to know the real cause of the problem. How I can know the error? For this we are having Fault Contract. Fault Contract provides documented view for error occurred in the
service to client. This helps us to easy identity, what error has occurred.

[ServiceContract()]
public interface ISimpleCalculator
{
[OperationContract()]
int Add(int num1, int num2);
}
//Service implementation
public class SimpleCalculator : ISimpleCalculator
{
public int Add(int num1, int num2)
{
//Do something
throw new Exception("Error while adding number");
}
}
Step 2: On client side code. Exceptions are handled using try-Catch block. Even though I have capture the exception when I run the application. I got the message that exceptions are not handled properly.

{
MyCalculatorServiceProxy.MyCalculatorServiceProxy proxy
= new MyCalculatorServiceProxy.MyCalculatorServiceProxy();
Console.WriteLine("Client is running at " + DateTime.Now.ToString());
Console.WriteLine("Sum of two numbers... 5+5 =" + proxy.Add(5, 5));
Console.ReadLine();
}
catch (Exception ex)
{ Console.WriteLine(ex.Message);
Console.ReadLine();
}
Step 3: Now if you want to send exception information form service to client, you have to use FaultException as shown below.
public int Add(int num1, int num2)
{
//Do something
throw new FaultException("Error while adding number");
}
Step 4: Output window on the client side is show below.
Step 5: You can also create your own Custom type and send the error information to the client using FaultContract. These are the steps to be followed to create the fault contract.

Decorate the service operation with the FaultContract attribute and specify the type name.
Raise the exception from the service by creating an instance and assigning properties of the custom exception.
Step 6: Defining the type using Data Contract
[DataContract()]
public class CustomException
{
[DataMember()]
public string Title;
[DataMember()]
public string ExceptionMessage;
[DataMember()]
public string InnerException;
[DataMember()]
public string StackTrace;
}
Step 7: Decorate the service operation with the FaultContract
[ServiceContract()]
public interface ISimpleCalculator
{
[OperationContract()]
[FaultContract(typeof(CustomException))]
int Add(int num1, int num2);
}
Step 8: Raise the exception from the service
public int Add(int num1, int num2)
{
//Do something
CustomException ex = new CustomException();
ex.Title = "Error Funtion:Add()";
ex.ExceptionMessage = "Error occur while doing add function.";
ex.InnerException = "Inner exception message from serice";
ex.StackTrace = "Stack Trace message from service.";
throw new FaultException(ex,"Reason: Testing the Fault contract") ;
}
Step 9: On client side, you can capture the service exception and process the information, as shown below.
try
{
MyCalculatorServiceProxy.MyCalculatorServiceProxy proxy
= new MyCalculatorServiceProxy.MyCalculatorServiceProxy();
Console.WriteLine("Client is running at " + DateTime.Now.ToString());
Console.WriteLine("Sum of two numbers... 5+5 =" + proxy.Add(5, 5));
Console.ReadLine();
}
catch (FaultException<MyCalculatorService.CustomException> ex)
{
//Process the Exception
}
Instance Management:
Instance management refers to the way a service handles a request from a client.
Basically there are 3 instance modes in WCF:
Per-Call instance mode
Per-Session instance mode
Singleton Instance Mode
Instance mode can be configured using ServiceBehavior attribute.
[ServiceContract()]
public interface IMyService
{
[OperationContract]
int MyMethod();
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class MyService:IMyService
{
public int MyMethod()
{
//Do something
}
}

Per-Call Instance:
A Service instance will be created for each client request. This Service instance will be disposed after response is sent back to client.
1. Client call the proxy
2. Proxy forward the call to service
3. WCF create service instance.
4. Service Instance calls the method
5. Method returns value to the client
6. WCF call IDisposable on service instance.

Create the service contract called IMyService and implement the interface. Add service behavior attribute to the service class and set the InstanceContextMode property to PerCall as show below.
[ServiceContract()]
public interface IMyService
{
[OperationContract]
int MyMethod();
}
Step 2:
In this implementation of MyMethod operation, increment the static variable(m_Counter). Each time while making call to the service, m_Counter variable is incremented and return the value to the client.
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public class MyService:IMyService
{
static int m_Counter = 0;
public int MyMethod()
{
m_Counter++;
return m_Counter;
}
}
Step 3:
Client side, create the proxy for the service and call "myMethod" operation multiple time.
static void Main(string[] args)
{
Console.WriteLine("Service Instance mode: Per-Call");
Console.WriteLine("Client making call to service...");
//Creating the proxy on client side
MyCalculatorServiceProxy.MyServiceProxy proxy =
new MyCalculatorServiceProxy.MyServiceProxy();
Console.WriteLine("Counter: " + proxy.MyMethod());
Console.WriteLine("Counter: " + proxy.MyMethod());
Console.WriteLine("Counter: " + proxy.MyMethod());
Console.WriteLine("Counter: " + proxy.MyMethod());
Console.ReadLine();
}
All requests to service return '1', because we configured the Instance mode to Per-Call. Service instance will created for each request and value of static variable will be set to one. While return back, service instance will be disposed.
Per-Session Service:
When WCF service is configured for Per-Session instance mode, logical session between client and service will be maintained.

Step 1:
Create the service contract called IMyService and implement the interface. Add service behavior attribute to the service class and set the InstanceContextMode property to PerSession as show below.
[ServiceContract()]
public interface IMyService
{
[OperationContract]
int MyMethod();
}
Step 2:
In this implementation of MyMethod operation, increment the static variable (m_Counter). Each time while making call to the service, m_Counter variable will be incremented and return the value to the client.
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class MyService:IMyService
{
static int m_Counter = 0;
public int MyMethod()
{
m_Counter++;
return m_Counter;
}
}
Step 3:
Client side, create the proxy for the service and call "myMethod" operation multiple time.
static void Main(string[] args)
{
Console.WriteLine("Service Instance mode: Per-Session");
Console.WriteLine("Client making call to service...");
//Creating the proxy on client side
MyCalculatorServiceProxy.MyServiceProxy proxy =
new MyCalculatorServiceProxy.MyServiceProxy();
Console.WriteLine("Counter: " + proxy.MyMethod());
Console.WriteLine("Counter: " + proxy.MyMethod());
Console.WriteLine("Counter: " + proxy.MyMethod());
Console.WriteLine("Counter: " + proxy.MyMethod());
Console.ReadLine();
}
All request to service return incremented value (1, 2, 3, 4), because we configured the instance mode to Per-Session. Service instance will be created once the proxy is created at client side. So each time request is made to the service, static
variable is incremented. So each call to MyMethod return incremented value.

Singleton Service:
When WCF service is configured for Singleton instance mode, all clients are independently connected to the same single instance. This singleton instance will be created when service is hosted and, it is disposed when host shuts down.
Step 1:
Create the service contract called IMyService and implement the interface. Add service behavior attribute to the service class and set the InstanceContextMode property to Single as show below.
[ServiceContract()]
public interface IMyService
{
[OperationContract]
int MyMethod();
}
Step 2:
In this implementation of MyMethod operation, increment the static variable(m_Counter). Each time while making call to the service, m_Counter variable is incremented and return the value to the client
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class MyService:IMyService
{
static int m_Counter = 0;
public int MyMethod()
{
m_Counter++;
return m_Counter;
}
}
Step 3:
Client side, create the two proxies for the service and made a multiple call to MyMethod.
static void Main(string[] args)
{
Console.WriteLine("Service Instance mode: Singleton");
Console.WriteLine("Client 1 making call to service...");
//Creating the proxy on client side
MyCalculatorServiceProxy.MyServiceProxy proxy =
new MyCalculatorServiceProxy.MyServiceProxy();
Console.WriteLine("Counter: " + proxy.MyMethod());
Console.WriteLine("Counter: " + proxy.MyMethod());
Console.WriteLine("Counter: " + proxy.MyMethod());

//Creating new proxy to act as new client
MyCalculatorServiceProxy.MyServiceProxy proxy2 =
new MyCalculatorServiceProxy.MyServiceProxy();
Console.WriteLine("Counter: " + proxy2.MyMethod());
Console.WriteLine("Counter: " + proxy2.MyMethod());
Console.ReadLine();
}
When two proxy class made a request to service, single instance at service will handle it and it return incremented value (1, 2, 3, 4), because instance mode is configured to 'Single'. Service instance is created when it is hosted. So this instance will remain till host is shutdown.

Basically service instance is hosted in a context.When session starts, context is created and when it closes, context is terminated. WCF provides the option of separating the two lifetimes and deactivating the instance separately from its context.

RealeaseInstanceMode.None
RealeaseInstanceMode.BeforeCall
RealeaseInstanceMode.AfterCall
RealeaseInstanceMode.BeforeAndAfterCall

public interface ISimpleCalculator
{
[OperationContract()]
int Add(int num1, int num2);
}
[OperationBehavior(ReleaseInstanceMode=ReleaseInstanceMode.BeforeCall]
public int Add(int num1, int num2)
{
return num1 + num2;
}
ReleaseInstanceMode.None:It will not affect the instance lifetime. By default ReleaseInstanceMode property is set to 'None'.
ReleaseInstanceMode.BeforeCall:
It will create new instance before a call is made to the operation.If the instance is already exist,WCF deactivates the instance and calls Dispose() before the call is done.
ReleaseInstanceMode.AfterCall:
It will deactivate the instance after call is made to the method.
ReleaseInstanceMode.BeforeAndAfterCall:
It will create new instance of object before a call and deactivates the instance after call. It has combined effect of using ReleaseInstanceMode.BeforeCall and ReleaseInstanceMode.AfterCall

We can also explicitly deactivate instance using InstanceContext object as shown below.

public interface IMyService
{
[OperationContract]
void MyMethod();
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class MyService:IMyService
{
public void MyMethod()
{
//Do something
OperationContext.Current.InstanceContext.ReleaseServiceInstance();
}
}
Durable Service:
Durable services persist service state information even after service host is restarted or Client. Durable services have the capability to restore their own state when they are recycled. It can use SQL database for maintaining instance state.
We can also maintain session using WCF sessions, but content in the session environment is not persisted by default. If the service is shut down or client closes the proxy, data will be lost. But in case of Durable service it is still maintained.
When a client make a request to the service, instance of the service is serialized, a new GUID is generated. This serialized instance xml and key will be saved in the database. We will call this GUID as instanceID. Service will send the instanceID to the client, so later it can use this id to get the instance state back. Even when client is shut down, instanceId will be saved at the client side. So when ever client opening the proxy, it can get back the previous state.

Durable service can be implemented using [DurableService()] attribute. It takes 'CanCreateInstance' and 'CompletesInstance'
property to mention on which operation instance state has to be saved and destroyed.

CompletesInstance = true: Deletes the persisted instance from the datastore.
[Serializable]
[DurableService()]
public class MyService :IMyservice
{
[DurableOperation(CanCreateInstance = true)]
public int StartPersistance()
{
//Do Something
}
[DurableOperation(CompletesInstance = true)]
public void EndPersistence()
{
//Do Something
}
}

Let us understand more about the durable service by creating Simple Calculator service which persist the instance state in SQL server database.
Step 1:
Start the Visual Studio 2008 and click File->New->Web Site. Select the 'WCF Service' as shown below.
Step 2:
Create interface and decorate with Service and Operation contract.
[ServiceContract()]
public interface ISimpleCalculator
{
[OperationContract]
int Add(int num);

int Subtract(int num);
[OperationContract]
int Multiply(int num);
[OperationContract]
void EndPersistence();
}
Step 3:
You need to add [Serializable] And [DurableService()] attribute to the service implementation. Set CanCreateInstance = true
property to the operation in which instance state has to be persisted and set CompletesInstance = true when state has to be destroyed. In this implementation, we are going to persist the 'currentValue' variable value to the database.

using System.ServiceModel;
using System.Text;
using System.ServiceModel.Description;

[DurableService()]
public class SimpleCalculator :ISimpleCalculator
{
int currentValue = default(int);
[DurableOperation(CanCreateInstance = true)]
public int Add(int num)
{
return (currentValue += num);
}
[DurableOperation()]
public int Subtract(int num)
{
return (currentValue -= num);
}
[DurableOperation()]
public int Multiply(int num)
{
return (currentValue *= num);
}
[DurableOperation(CompletesInstance = true)]
public void EndPersistence()
{
}

Before configuring the database information in the durable service, you need to set up DataStore environment. Microsoft provides inbuilt sqlPersistance provider. To set up the database environment, run the these sql query located at following
location 'C:\Windows\Microsoft.NET\Framework\v3.5\SQL\EN'

SqlPersistenceProviderLogic.sql

In order to support durable service, you need to use Context binding type. <persistenceProvider> tag is used to configure the persistence provider.

<services>
<service name="SimpleCalculator" behaviorConfiguration="ServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="wsHttpContextBinding"
bindingConfiguration="browConfig" contract="ISimpleCalculator">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<persistenceProvider type="System.ServiceModel.Persistence.SqlPersistenceProviderFactory,
System.WorkflowServices, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" connectionStringName="DurableServiceStore"
persistenceOperationTimeout="00:00:10" lockTimeout="00:01:00" serializeAsText="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpContextBinding >
<binding name="browConfig" >
<security mode="None"></security>
</binding>
</wsHttpContextBinding>
</bindings>
</system.serviceModel>
<connectionStrings>
<add name="DurableServiceStore" connectionString="Data Source=saravanakumar;Initial Catalog
=DurableServiceStore;Integrated Security=True"/>
</connectionStrings>

Create the console client application and name it as DurableServiceClient

System.ServiceModel
System.WorkflowService

Step 9:
Create the Helper class called it as Helper.cs. This helper class is used to Store, Retrieve and set the context at the client side. Context information will be saved in 'token_context.bin' file. Copy and paste the below code to your helper file.

Helper.cs:
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Net;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public class Helper
{
static readonly String TokenContextFileName = "token_context.bin";
public static IDictionary<String, String> LoadContext()
{
IDictionary<String, String> ctx = null;
try
{
using (FileStream fs = new
FileStream(TokenContextFileName, FileMode.Open, FileAccess.Read))
{
BinaryFormatter bf = new BinaryFormatter();
ctx = bf.Deserialize(fs) as IDictionary<String, String>;
fs.Close();
}
}
catch (Exception ex)
{ }
return ctx;
}
public static void SaveContext(IClientChannel channel)
{
IDictionary<String, String> ctx = null;
IContextManager cm = channel.GetProperty<IContextManager>();
if (cm != null)
{
ctx = cm.GetContext() as IDictionary<String, String>;
try
{
using (FileStream fs
= new FileStream(TokenContextFileName, FileMode.CreateNew))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, ctx);
fs.Close();
}
}
catch (Exception ex)
{ }
}
}
public static void DeleteContext()
{
try
{
File.Delete(TokenContextFileName);
}
catch (Exception ex)
{ }
}
public static void SetContext(IClientChannel channel,
IDictionary<String, String> ctx)
{
IContextManager cm = channel.GetProperty<IContextManager>();
if (cm != null)
{
cm.SetContext(ctx);
}
}
}
Step 10:
In the main method, I was creating the proxy for the service and calling the Add operation. Call to this method will add instance state to the database. Now I have closed the proxy and creating new proxy instance. When I call the Subtract and

Multiply operation, it will operate on the previously saved value (instance state).

static void Main(string[] args)
{
//Create the proxy for the service
SimpleCalculatorService.SimpleCalculatorClient client= new SimpleCalculatorService.SimpleCalculatorClient
"WSHttpContextBinding_ISimpleCalculator");
int currentValue = 0;
//Call the Add method from the service
currentValue = client.Add(10000);
Console.WriteLine("The current value is {0}", currentValue);
//Save the Context from the service to the client
Helper.SaveContext(client.InnerChannel);
//Close the proxy
client.Close();
//Create new Instance of the proxy for the service
client = new SimpleCalculatorService.SimpleCalculatorClient("WSHttpContextBinding_ISimpleCalculator");
//Load the context from the client to start from saved state
IDictionary<string,string> cntx=Helper.LoadContext();
//Set Context to context manager
Helper.SetContext(client.InnerChannel, cntx);
//Call the Subtract and Multiply method from service
currentValue = client.Subtract(2);
Console.WriteLine("The current value is {0}", currentValue);
currentValue = client.Multiply(5);
Console.WriteLine("The current value is {0}", currentValue);
//Delete the context from the client
Helper.DeleteContext();
//Remove persistance state from the server
client.EndPersistence();
Console.WriteLine("Press <ENTER> to shut down the client.");
Console.ReadLine();
client.Close();
}

Throttling:
WCF throttling provides some properties that you can use to limit how many instances or sessions are created at the application level. Performance of the WCF service can be improved by creating proper instance.

Attribute Description
maxConcurrentCalls - Limits the total number of calls that can currently be in progress across all service instances. The default is 16.
maxConcurrentInstances - The number of InstanceContext objects that execute at one time across a ServiceHost. The default is Int32.MaxValue.
maxConcurrentSessions - A positive integer that limits the number of sessions a ServiceHost object can accept. The default is 10.

Service Throttling can be configured either Adminstractive or Programatically

Administrative (configuration file)
Using <serviceThrottling> tag of the Service Behavior, you can configure the maxConcurrentCalls, maxConcurrentInstances , maxConcurrentSessions property as shown below.

<system.serviceModel>
<services >
<service behaviorConfiguration="ServiceBehavior" name="MyService">
<endpoint address="" binding="wsHttpBinding" contract="IMyService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true "/>
<serviceThrottling maxConcurrentCalls="500"
maxConcurrentInstances ="100" maxConcurrentSessions ="200"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

Programming Model
Use ServiceThrottlingBehavior object to set concurrent calls, session and instance property.

ServiceHost host = new ServiceHost(typeof(MyService));
ServiceThrottlingBehavior throttle = host.Description.Behaviors.Find();
if (throttle == null)
{
throttle = new ServiceThrottlingBehavior();
throttle.MaxConcurrentCalls = 500;
throttle.MaxConcurrentSessions = 200;
throttle.MaxConcurrentInstances = 100;
host.Description.Behaviors.Add(throttle);
}
host.Open();

Transfer mode
If data transfer is taking place through WCF service, message size will play major role in performance of the data transfer. Based on the size and other condition of the data transfer, WCF supports two modes for transferring messages
Buffer transfer
When the client and the service exchange messages, these messages are buffered on the receiving end and delivered only once the entire message has been received. This is true whether it is the client sending a message to the service or the service returning a message to the client. As a result, when the client calls the service, the service is invoked only after the client's message has been received in its entirety; likewise, the client is unblocked only once the returned message with the results of the invocation has been received in its entirety.
Stream transfer
When client and Service exchange message using Streaming transfer mode, receiver can start processing the message before it is completely delivered. Streamed transfers can improve the scalability of a service by eliminating the requirement for large memory buffers. If you want to transfer large message, streaming is the best method.
StreamRequest
In this mode of configuration, message send from client to service will be streamed
StreamRespone
In this mode of configuration, message send from service to client will be streamed.

Configuration
<system.serviceModel>
<services >
<service behaviorConfiguration="ServiceBehavior" name="MyService">
<endpoint address="" binding="netTcpBinding"
bindingConfiguration="MyService.netTcpBinding" contract="IMyService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true "/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings >
<netTcpBinding>
<binding name="MyService.netTcpBinding" transferMode="Buffered" closeTimeout ="0:01:00" openTimeout="0:01:00"></binding>
</netTcpBinding>
</bindings>
</system.serviceModel>

Differences between Buffered and Streamed Transfers
Buffered:
Target can process the message once it is completely received.
Performance will be good when message size is small
Native channel shape is IDuplexSessionChannel
Streamed:
Target can start processing the data when it is partially received
Performance will be good when message size is larger(more than 64K)
Native channels are IRequestChannel and IReplyChannel
Operations:
Three modes of communication between client and service are

1. Request- Replay:
By default all WCF will operated in the Request-Replay mode. It means that, when client make a request to the WCF service and client will wait to get response from service (till receiveTimeout). After getting the response it will start executing the
rest of the statement. If service doesn't respond to the service within receiveTimeout, client will receive TimeOutException.

Apart from NetPeerTcpBinding and the NetMsmqBinding all other bindings will support request-reply operations.
2. One-Way:
In One-Way operation mode, client will send a request to the server and does not care whether it is success or failure of service execution. There is no return from the server side, it is one-way communication.
Client will be blocked only for a moment till it dispatches its call to service. If any exception thrown by service will not reach the server.

Client can continue to execute its statement, after making one-way call to server. There is no need to wait, till server execute. Sometime when one-way calls reach the service, they may not be dispatched all at once but may instead be queued up
on the service side to be dispatched one at a time, according to the service's configured concurrency mode behavior. If the number of queued messages has exceeded the queue's capacity, the client will be blocked even if it's issued a one-way call.

However, once the call is queued, the client will be unblocked and can continue executing, while the service processes the operation in the background.
Definition:
One-way operation can be enabled by setting IsOneWay property to true in Operation contract attribute.

[ServiceContract]
public interface IMyService
{
[OperationContract(IsOneWay=true)]
void MyMethod(EmployeeDetails emp);
}

One-Way Operations and Sessionful Services:
Let us see the example, what will happen when you use the one-way communication with Sessionful service.

[ServiceContract(SessionMode = SessionMode.Required)]
interface IMyContract
{
[OperationContract(IsOneWay = true)]
void MyMethod();
}

As per above configuration, when client makes one-way call using MyMethod() operation and if it close the proxy. Client will be blocked until operation completes. It will be good practice, that one-way operation should be applied on per-call and singleton service.

Suppose If you want to make use of One-way operation in Sessionful service, use in the last operation of the service which will terminate the session. This operation should not return any value.

[ServiceContract(SessionMode = SessionMode.Required)]
interface IMyContract
{
[OperationContract]
void MyMethod1();
[OperationContract]
string MyMethod2();
[OperationContract(IsOneWay = true, IsInitiating = false,
IsTerminating = true)]
string CloseSessionService(int id);
}

One-Way Operations and Exceptions:
Suppose when we are using BasicHttpBinding or WSHttpBinding, i.e. no transport session is used, if any exception throw by service will not affect the client. Client can make a call to the service using same proxy

[ServiceContract]
interface IMyContract
{
[OperationContract(IsOneWay = true)]
void MethodWithError( );
[OperationContract]
void MethodWithoutError( );
}
//Client side without transport session
MyContractClient proxy = new MyContractClient( );
proxy.MethodWithError( ); //No exception is thrown from serivce
proxy.MethodWithoutError( ); //Operation will execute properly
proxy.Close( );

In the presence of transport session, any exception thrown by service will fault the client channel. Client will not be able to make new call using same proxy instance.

//Client side transport session
MyContractClient proxy = new MyContractClient( );
proxy.MethodWithError( );
proxy.MethodWithoutError( ); //Can not executre because channel is faulted
proxy.Close( );
3. Callback:
Till now we have seen that the all clients will call the service to get the things done. But WCF also provides the service to call the client. In which, service will act as client and client will act as service.

HTTP protocols are connectionless nature, so it is not supported for callback operation. So BasicHttpBinding and WSHttpBinding cannot be used for this operation.

WCF support WSDualHttpBinding for call back operation.
All TCP and IPC protocols support Duplex communication. So all these binding will be used for callback operation.

Defining and configuring a callback contract:
Callback service can be enabled by using CallbackContract property in the ServiceContract attribute. In the below example you can find the decalration of the callback contract and it is configured in the ServiceContract attribute.

public interface IMyContractCallback
{
[OperationContract]
void OnCallback();
}
[ServiceContract(CallbackContract = typeof(IMyContractCallback))]
public interface IMyContract
{
[OperationContract()]
void MyMethod();
}

Client Callback Setup:
As I said earlier, in callback operation client will act as service and service will act as client. So client has to expose a callback endpoint to the service to call. In the earlier part of the tutorial I have mention that InstanceContext is the execution scope of inner most service instance. It provides a constructor that takes the service instance to the host.
IMyContractCallback callback=new MyCallback();
InstanceContext cntx=new InstanceContext(callback);

MyServiceClient proxy = new MyServiceClient(cntx);
proxy.MyMethod();

The client must use a proxy that will set up the bidirectional communication and pass the callback endpoint reference to the service. This can be achieved by creating the proxy using DuplexClientBase

class MyServiceClient:DuplexClientBase,IMyContract
{
public MyServiceClient(InstanceContext callbackCntx)
: base(callbackCntx)
{
}
public void MyMethod()
{
base.Channel.MyMethod();
}
}

Service-Side Callback Invocation:
The client-side callback endpoint reference is passed along with every call the client makes to the service, and it is part of the incoming message. The OperationContext class provides the service with easy access to the callback reference via the
generic method GetCallbackChannel<T>( ). Service can call the client side callback method using reference e to the client side callback instance. The following code shows the callback method invocation.
IMyContractCallback
callbackInstance=OperationContext.Current.GetCallbackChannel();
callbackInstance.OnCallback();
one way Operation:
One way calls are useful for scenarios where you want to sure that the message was delivered, but don't care whether the message was processed or not.
Once the Client issues the call , WCF generates the request message and there is no corresponding response message for that. No Service side Exception will make their way to client.
A one way service call doesn't wait the call to be processed, only to be delivered - where delivery includes deserialization of the request. Once this has happened WCF send the response and start processing the operation on a separate thread.
When there is no transport session; means when BasicHttpBinding or wsHttpBinding is used; if an Exception takes place during the invocation of one-way operation, the client is unaffected and can continue to issue call on the same proxy
instance.
One-way property could only be set true to the operations that are returning Void. On any other return type it would throw error while loading the service.
Exception Handling:
The following options are provided to handle exceptions in WCF:
Using returnUnknownExceptionsAsFaults
Using FaultException
Using IErrorHandler
WCF provides an option to raise the exception automatically as a Soap Fault. To enable this option, set returnUnknownExceptionsAsFaults=‘True’ in the service behavior setting in the application configuration file under system.servicemodel.
<behaviors>
<behavior name="OrderingServiceBehavior"
returnUnknownExceptionsAsFaults="True">
</behavior>
</behaviors>
When you use the returnUnknownExceptionsAsFaults option, the client will receive an UnknownFaultException instead of a CommuncationException. The returnUnknownExceptionsAsFaults option should only be used during debugging.
http://www.wcftutorial.net/Fault-Contract.aspx
FaultContract is an attribute in WCF used to specify the type of exception that can be raised by that service.
FaultException is used in WCF to create a Soap Fault. Using the Fault Exception, you can wrap .NET exception or any custom object into a Soap Fault.
If the FaultContract contract is not specified, the clients receive all the exceptions as unknowfaultexceptions even if the exception is raised as a FaultException for an ApplicationException.
[OperationContract()]
[FaultContract(typeof(ApplicationException))]
void CreateOrderWithFaultException(Order order);
FaultException approach is the best approach for handling exception in WCF. In this approach,we have 2 options, one is to raise the .Net exception and the other is to raise it with custom object. You should always opt for the custom object option, as it would not expose all the details of .Net exception to the client, instead it sends only the required information to the client as a custom object. Another advantage of this option is that it will work well in other platform clients, as custom object type is described in WSDL.
In the case of .Net exception type, it is not described in WSDL and hence other platform clients would not understand it. You should use .Net exception option only when you know that both the client and service are using WCF and the client needs to get the exact .Net exception that occurred in the WCF service.
Using IErrorHandler:
With IErrorHandler approach, you can intercept all the exceptions raised inside a service using IErrorHandler. If you implement IErrorHandler interface methods in your service, you can intercept all the exceptions and you can “log and suppress” the exceptions or you can “log and throw” them as FaultException.

No comments:

Post a Comment