WCF 4.0 Features: Part #1

WCF 4 comes with many of new features for better developer experience. There is high integration with workflow service. Making WCF REST service more developer friendly and Configuration less WCF service. In short WCF 4 tries to address common scenario easily and at the same time gives us more options to communicate in between service and client.

Below are the few of new features of WCF 4.0

1. Dynamic Service and End Point discovery

2. Intermediate Routing Pattern ( Generic Routing Services)

3. Discovery announcement

4. Simplified Configuration

5. Protocol bridging and Fault tolerance

6. Default End Points.

7. .svc-less activation of REST services or making REST URI nice.

8. Default Protocol Mapping

9. Help page enabled for WCF Rest service and many more.

In this article we will see in detail three exciting features of WCF 4.0. and in further articles we will see the other features

In this article we are going to see

1. EndPoint Discovery

2. Default EndPoints

3. Help page enabled for WCF REST Service

Problem

People say; you need to know only ABC of a service to expose End Point of that service. And client or service consumer needs to know only End Point to consume the service. But wait for a while here, and think; what if? Binding need to change at the service side from basic to WS over HTTP, This is very basic change but to accommodate this client has to update the service again. And this is very much error prone. It is very tedious task to update client about all the basic frequent change at the service side. To solve this issue, there should be some mechanism and that is called End Point Discovery or Dynamic Service.

In absolute technical words

WCF 4.0 supports WS –Discovery standard or protocol.

WS-Discovery Standard

1. This is a multicast protocol that issues SOAP message over UDP,

2. WS-Discovery is a Standard that defines a lightweight discovery mechanism for discovering services based on multicast messages. It enables a service to send a Hello announcement message when it is initialized and a Bye message when is removed from the network.

3. Client or consumer can discover services by multicasting a Probe message to which a service can reply with a ProbeMatch message containing the information necessary to contact the service.

4. Client or consumer can find services that have changed endpoint by issuing a Resolve message to which respond with a ResolveMatchmessage.

So, we can say WS –Discovery is a UDP based multicast message exchange. This message receives End Point information from Service and uses this as discovery information. Client uses discovery information to discover the available service on the network.

WCF Service Discovery API

WCF provides, WCF Discovery API for dynamic publish and discovery of web service using WS –Discovery protocol. This API helps service to publish them and helps client to find service on the network.

Modes

clip_image002

Managed Mode

1. In managed mode there is a centralized server called a discovery proxy that services use to publish themselves and clients use to retrieve information about available services.

2. When a new service starts up it sends an announcement message to the discovery proxy.

3. The discovery proxy saves information about each available service to storage.

4. When a client must search for a service it sends a Probe request to the discovery proxy and it determines whether any of the services that have been published match the request.

5. If there are matches the discovery proxy sends a ProbeMatch response back to the client.

6. The client can then contact the service directly using the service information returned from the proxy.

Ad-Hoc Mode

1. There is no centralized server.

2. Service announcements and client requests are sent in a multicast fashion.

3. If a service is configured to send out a Hello announcement on start up, it sends it out over a well-known, multicast address using the UDP protocol.

4. Therefore, clients have to actively listen for these announcements and process them accordingly.

5. When a client issues a Probe request for a service it is also sent over the network using a multicast protocol.

6. Each service that receives the request determines whether it matches the criteria in the Probe request and responds directly to the client with a ProbeMatch message if the service matches the criteria specified in the Probe request.

Sample

In this sample, we will create a very basic service and at the client side, first client will discover the service in Ad-Hoc mode and then consume that.

To run and go through this sample, you need Visual Studio 2010 Beta.

To make a service discoverable, a ServiceDiscoveryBehavior must be added to the service host and a discovery endpoint must be added to specify where to listen for and send discovery message

Step1

Open VS2010. Create a new project by choosing WCF Service Application Project template.

Step 2

Delete all the code which is generated by Visual studio. After deleting Contract and Service Implantation is as follows.

IService1.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfService1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetMessage(string  msg);
}
}

Service1.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace WcfService1
{
public class Service1 : IService1
{
public string GetMessage(string msg)
{
return msg;
}

}
}

The above is simple Service Contract and implantation of that.

Step3

Open Web.Config file. And modify the System.ServiceModel. Add the code which in red rectangle below.

Web.Config


<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="WcfService1.Service1Behavior">
<endpoint address="" binding="wsHttpBinding" contract="WcfService1.IService1">

<identity>
<dns value="localhost"/>
</identity>
</endpoint>

<endpoint name ="udpDiscovery" kind ="udpDiscoveryEndpoint" />

<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService1.Service1Behavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>

<serviceDiscovery />

</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

Explanation of Config file

1. One new End Point is being added.

2. Kind of newly added End Point is udpDiscoveryEndpoint.

3. This End Point will be used to discover the service.

4. ServiceDiscovery behavior is also get added.

Step 4

Press F5 to run the service. Service will get hosted in ASP.Net web server.

clip_image006

Step 5

Add a new console project in solution.

Step 6

Add Reference of System.ServiceModel.Discovery.dll in console project.

clip_image007

Step 7

Add namespace using System.ServiceModel.Discovery;

Program.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication1.ServiceReference1;
using System.ServiceModel;
using System.ServiceModel.Discovery;

namespace ConsoleApplication1

{
class Program

{

static void Main(string[] args)

{

DiscoveryClient discoverclient = new DiscoveryClient(new UdpDiscoveryEndpoint());

FindResponse response = discoverclient.Find(new FindCriteria(typeof(IService1)));

EndpointAddress address = response.Endpoints[0].Address;

Service1Client client = new Service1Client(new  WSHttpBinding(), address);

string str= client.GetMessage("Hello WCF 4 ");

Console.WriteLine(str);

Console.ReadKey(true);

}

}
}

Explanation of the code

1. We are making object of DiscoveryClient class. This class is user to discover available service.

2. In constructor of this class, we are passing UdpDiscoveryEndPoint of the service.

3. Then we are calling Find method with contract name as argument to get FindResponse.

4. Now FindResponse variable having all the available address for contract passed in Find method.

5. We are creating the client proxy and passing discovered address as argument.

6. Calling the service operation on the client proxy.

Output

clip_image009

Default End Points and Protocol mapping

For a normal developer like me, had a great challenge working with WCF 3.x was configuration of End Points in config file. Developer had to add endpoints to setup a WCF service. In WCF 4, Defualt End Point is associated with the service, if we don’t configure any WCF endpoint.

Walkthrough

To see how Default EndPoint works follow the steps below,

Step1

Create a WCF service application.

Let us create two service contracts

IService1.cs


[ServiceContract]
public interface IService1
{

[OperationContract]
string GetData();
}

IService2.cs


[ServiceContract]
public interface IService2
{
[OperationContract]
string GetMessage();
}

Now let us implement the service as below,


public class Service1 : IService1, IService2
{
public string GetData()
{
return "Hello From Iservice1 ";

}

public string GetMessage()
{
return " Hello From Iservice2";
}

Step 2

Now we will host this service in a console application, Create a new console application project.

Add reference of WCF service application project and also add reference of System.serviceModel in the console application project.

Note: There is no App.Config associated with console application.

clip_image011

Here, we are registering two base addresses with the servicehost. One for http binding and other for nettcp binding.

Now we don’t have any configuration for the service EndPoint . ServiceHost will create default EndPoints .

Now ServiceHost will configure EndPoints for two base addresses


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using WcfService1;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{

ServiceHost host = new ServiceHost(typeof(WcfService1.Service1),
new Uri("<a href="http://localhost:8080/service">http://localhost:8080/service</a>"),
new Uri("net.tcp://localhost:8081/service"));

host.Open();
foreach (ServiceEndpoint se in host.Description.Endpoints)
{
Console.WriteLine("Address: " +  se.Address.ToString() +
"  Binding: " + se.Binding.Name +
" Contract :"+ se.Contract.Name);
}

Console.ReadKey(true);

}
}
}

Output would be

clip_image013

The default protocol mapping for default EndPoints are mapped as below,

clip_image015

Since HTTP is mapped with basicHttpBinding , so we got the default EndPoint with basicHttpBinding.

Default EndPoint will only get created if there is not a single Endpoint configured. If we add any single EndPoint then all then there won’t be any default EndPoint get configured.

If we add one EndPoint as below,

clip_image017

We added one service EndPoint and now the output we would get for below code ad below,


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using WcfService1;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{

ServiceHost host = new ServiceHost(typeof(WcfService1.Service1),
new Uri("<a href="http://localhost:8080/service">http://localhost:8080/service</a>"),
new Uri("net.tcp://localhost:8081/service"));

host.AddServiceEndpoint(typeof(IService1),
new WSHttpBinding(),
"myBinding");

host.Open();
foreach (ServiceEndpoint se in host.Description.Endpoints)
{
Console.WriteLine("Address: " +  se.Address.ToString() +
"  Binding: " + se.Binding.Name +
" Contract :"+ se.Contract.Name);
}

Console.ReadKey(true);

}
}
}

Output

clip_image019

Now we see that if we configure EndPoint then WCF does not support default Endpoints.

If we closely look at the output that by default WCF maps protocol to binding as below.

clip_image020

So if we are not configuring any EndPoint , then for http type base address in default EndPoint created by WCF will have basicHttpBinding.

If we see the above mapping , by default http type is mapped to basicHttpBinding , net.tcp type is mapped to netTcpBinding and so on.

If we want to change this, we can change this default mapping

clip_image022

Now when we do the above change in the Web.Config file then when we do not define any EndPoint then for HTTP type base address, WCF will create the EndPoint with wsHttpBinding.

So to understand more, what I am talking about

1. Create a WCF Service application

2. Create a Service contract as below


[ServiceContract]
public interface IService1
{

[OperationContract]
string GetData();
}

3. Implement the Service as below


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace WcfService1
{

public class Service1 : IService1
{
public string GetData()
{
return "Hello From Iservice1 ";

}

}
}

4. Now we will host this service in a console application, Create a new console application project. Add reference of WCF service application project and also add reference of System.serviceModel in the console application project.

5. Right click on the console project and add app.config file to console project. Right the below configuration in App.Config


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<protocolMapping >
<add  scheme ="http" binding ="wsHttpBinding" bindingConfiguration ="" />
</protocolMapping>
</system.serviceModel>
</configuration>

6. Now write the below code to fetch the default Endpoint created by WCF


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using WcfService1;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{

ServiceHost host = new ServiceHost(typeof(WcfService1.Service1),
new Uri("<a href="http://localhost:8080/service">http://localhost:8080/service</a>"));

host.Open();
foreach (ServiceEndpoint se in host.Description.Endpoints)
{
Console.WriteLine("Address: " +  se.Address.ToString() +
"  Binding: " + se.Binding.Name +
" Contract :"+ se.Contract.Name);
}

Console.ReadKey(true);

}
}
}

And output we would get is

clip_image024

So we can see that how we modified the default mapping using Protocol mapping in System.ServiceModel

Enabling Help page for REST Service in WCF 4.0

WCF 4.0 provides us feature to eanable Help page on WCF REST Service.

Walkthrough

In this walkthrough we will see,

1. How to create a REST based service?

2. How to host a REST based service in Console application?

3. How to enable Help page for REST Service?

Follow the steps as below,

Step1

Create a New project. Select Console application as project type.

clip_image026

Step 2

Add a new project to same solution. Choose the project type as class library.

clip_image028

Step 3

Add below references in both projects console and service library

System.ServiceModel;

System.ServiceModel.Description;

System.ServiceModel.Web;

clip_image029

If you are not able to get System.ServiceModel.Web dll by default , when you are adding as Add Reference in your console application project and class library project , then follow the below steps

1. Right click on your console application project or class library project

2. Select properties from context menu

3. From Application tab, if you see by default .NET Framework 4 Client profile is selected. Change that to .NET Framework 4.0. So your target framework should be .NET Framework 4.0.

clip_image030

Now you should able to see all the dll when you add service reference in project.

Step 4

In this step, I will create contract of service

1. Open the Contract (Class Library project).

2. Delete Class1.

3. Right click and add a new item then select Interface from Code tab.

clip_image032

4. Make Interface as public and put ServiceContract attribute.

5. Declare two operation contracts. Make one attributed with WebGet and another attributed with Web Invoke.

IService.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace Contracts
{
[ServiceContract]
public  interface IService
{
[OperationContract]
[WebGet]
string GetMessage(string inputMessage);

[OperationContract]
[WebInvoke]
string PostMessage(string inputMessage);
}
}

Step 5

In this step, I will implement the contract in Service file. To do so,

1. Right click and add a class in Console application.

clip_image034

2. Give any name; I am giving name here Service of the class.

3. Implement the interface (Contract IService) in this class.

Service.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Contracts;

namespace SelfHostedRESTService
{
public  class Service :IService
{
public string GetMessage(string inputMessage)
{
return "Calling Get for you " + inputMessage;
}

public string PostMessage(string inputMessage)
{
return "Calling Post for you " + inputMessage;
}
}
}

Step 6

In this step, I will host the service in a console application. So to do so

1. Open Program.cs

2. Create instanced of WebServieceHostFactory

clip_image036

3. Add a service end point

clip_image038

4. Add service host behavior with help page enabled

clip_image040

As we know, REST service used webHttpBindding. And we are enabling Help page here.

Program.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using Contracts;

namespace SelfHostedRESTService
{
class Program
{
static void Main(string[] args)
{

WebServiceHost host = new WebServiceHost(typeof(Service), new Uri("<a href="http://localhost:8000">http://localhost:8000</a>"));
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "");

host.Description.Endpoints[0].Behaviors.Add(new WebHttpBehavior { HelpEnabled = true });
host.Open();
Console.WriteLine("Service is up and running");
Console.WriteLine("Press enter to quit ");
Console.ReadLine();
host.Close();
}
}
}

Step 7

Just press F5 to run the service.

clip_image042

Now once service is up and running, I can test,

To test the Help page, just type

http://localhost:8000/help

clip_image044

When you click on Get or Post link you will get below detail help.

clip_image046

In next article we will see some other features of WCF 4.0

3 responses to “WCF 4.0 Features: Part #1”

  1. […] WCF 4.0 Features: Part #1 (Dhananjay Kumar) […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create a website or blog at WordPress.com