WCF
Windows Communication Foundation (WCF) is part of .NET 3.0. WCF is a Microsoft platform for building distributed and interoperable applications.
Now, let's understand distributed and interoperable applications.
Distributed applications
A distributed application is an application where parts of it run on 2 or more computer nodes.
Interoperable applications
An appliction that can communicate with any other application built on any platform is called as an interoperable application.
Now what technology choices did we have before WCF to build distributed applications?
Now In this article you will see:
- Creation of a WCF service.
- Hosting the WCF service using a console application.
- Exposing 2 service endpoints.
- Creating Windows and a web client applications.
First of all we will understand why we use a WCF service and then we will create a WCF service. Let's understand an example.
If we have two clients then the first client has a Java web application to communicate with our service and to him interoperability is the main requirement, so he wants XML messages over the HTTP protocol.
So to satisfiy the client's requirements we will develop a service using ".Net Web Service" technology.
The second client using a Windows application to communicate with our service is a Windows application that is also a .NET application so for him the performance is the main requirement and he wants a binary message format over TCP protocol, to satisfy this client requirement we will create the same service in a different tecnology that is".Net Remoting".
Now just because the clients, protocol and message formats are different we need to create the service in different technologies.
With WCF we don't need to create either a Web service or .NET remoting services any more. We implement a single WCF service and expose two endpoints. The first endpoint exchanges XML messages over the HTTP protocol. For that we use basicHttpBinding so the interoperability requirement for the first client is met.
And the second endpoint exchanges binary messages over TCP protocol. For this we use netTcpBinding so the requirement of the second client is also met.
So here we are using a single WCF service and configuring two Endpoints to satisfy both of the two client requirements. If we have a third client with a requirement for a different message format and protocol then we will expose one more endpoint for him but the service doesn't change. In the configuration file we will just introduce another endpoint for him.
Creating a WCF service
Step 1
First create a class library project named HelloService.
Now delete the autogenerated class1.cs file.
Step 2
Now add a WCF Service named HelloService to this project.
Look here at the References. Two things have happend. It added a reference of the System.ServiceModel assembly, it is the core to WCF and all the attributes and classes that we use in a WCF Service is present in this assembly. The second thing is that it added the two class files HelloService.cs and IHelloService.cs.
Step 3
Now we look at the IHelloService.cs file with the following code. It has the interface IHelloService and that is created in the [ServiceContract] attribute just by decorating this interface with the [ServiceContract] attribute. We are turning this interface in the WCF service.
And this interface has the one method DoWork() that is created with the [OperationContract] attribute, in other words we are making this method available as part of this service to the client. If we have more methods and we want to make all those methods available in the service then we must define all those with the [OperationContract] attribute.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.Serialization;
- using System.ServiceModel;
- using System.Text;
-
- namespace HelloService
- {
-
- [ServiceContract]
- public interface IHelloService
- {
- [OperationContract]
- void DoWork();
- }
- }
Step 4
Now we will change the name of the method as GetMessage() with the name parameter by the following code.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.Serialization;
- using System.ServiceModel;
- using System.Text;
-
- namespace HelloService
- {
-
- [ServiceContract]
- public interface IHelloService
- {
- [OperationContract]
- string GetMessage(string name);
- }
- }
Step 5
Now we will see in the HelloService.cs file, here the class is HelloService and this class implements the interface IHelloService. Here we implement the method GetMessage() with the following code.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.Serialization;
- using System.ServiceModel;
- using System.Text;
-
- namespace HelloService
- {
-
- public class HelloService : IHelloService
- {
-
- public string GetMessage(string name)
- {
- return "Hello " + name;
- }
- }
- }
Now in the IHelloService.cs we have one [ServiceContract] and it has one [OpreationContract] meaning one operation that the client can invoke. In the HelloService.cs file we are implementing one [ServiceContract] method that is GetMessage(). So we complete the creation of WCF service.
Step 6
Now the second things is that now we will host the WCF service. For hosting we will create a console application to make things simple. There are many ways for hosting.
Let's add a console application to the service named HelloServiceHost.
Now add a ServiceModel reference to this console.
And we need to reference the service itself so add a HelloService reference.
Step 7
Now we need to specify a configuration for the service we made. Here we will create two endpoints within the host when we host the service.
Now we right-click on the project then seelct Add > New item > Application Configuration File.
So to this console application we should add an App.config file. To add this configuration file we will write some configuration for the Endpoints, using the following code.
- <?xml version="1.0" encoding="utf-8" ?>
- <configuration>
- <system.serviceModel>
- <services>
- <service name="HelloService.HelloService" behaviorConfiguration="mexBehaviour">
-
- <endpoint address="HelloService" binding="basicHttpBinding" contract="HelloService.IHelloService">
- </endpoint>
- <endpoint address="HelloService" binding="netTcpBinding" contract="HelloService.IHelloService">
- </endpoint>
- <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange">
- </endpoint>
- <host>
- <baseAddresses>
- <add baseAddress="http://localhost:8080/"/>
- <add baseAddress="net.tcp://localhost:8090/"/>
- </baseAddresses>
- </host>
- </service>
- </services>
- <behaviors>
- <serviceBehaviors>
- <behavior name="mexBehaviour">
- <serviceMetadata httpGetEnabled="true"/>
-
- </behavior>
- </serviceBehaviors>
- </behaviors>
- </system.serviceModel>
- </configuration>
Code Description: Here we are using three endpoints, one for HTTP protocol, the second for the TCP protocol and the third for the metadata exchange. Here three attributs are specified.
- Address: where our service is available.
- Binding: it supports the specific protocol or message format.
- Contract: Service contract means that all the operations are available in the service, it is an interface.
So we specify it by the name of the namespace and interface. Now here we specified baseAddress that is for where our service is available.
Now here we specified ServiceBehavior allows the exchange of metadata to the service.
Step 8
Now we set our service host as a startup project.
Now before run it we will open the service host first. Now see the program.cs file that is a console program. Here in the Main() method we need to open the service host for communication. Here we need to add the System.ServiceModel namespace and we get the ServiceHost class with the following code.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.ServiceModel;
-
- namespace HelloServiceHost
- {
- class Program
- {
- static void Main()
-
- {
- using (ServiceHost host = new ServiceHost(typeof(HelloService.HelloService)))
- {
-
- host.Open();
- Console.WriteLine("host started @ "+ DateTime.Now.ToString());
- Console.ReadLine();
- }
- }
- }
- }
Now we will run the HelloServiceHost and we will get the output as expected.
If we encounter an exception like this then we will run the console application in Visual Studio when Run As Administrator.
And now we will get output as expected.
Step 9
Now we will create a client application. To do that we open a new instance of Visual Studio and let's create an ASP.NET web application to satisfy the first client's requirement.
Step 10
Now before we create a client application we recall the HelloService App.config file where we specified one endpoint for the Metadata exchange. If we want a Web Service Description Language (WSDL) document of this service then that means when we visit the baseAddress URL with the mex address we should be able to get the WSDL document that is associated with the service.
Now we open a browser and write the baseadress http://localhost:8080/. Here the service is running and we get the WSLD document assosiated with this service.
Now we click on the WSDL document link and see that the document is similar to WSDL that we uses with webservices. Basically this document is used by the client to generate proxy classes that we use to communicate with the service.
Step 11
Now return to the webapplication and now we need to add a reference of the service itself.
Now provide the baseadress for getting the WSDL document like this:
Now look at here, it should add references here and automatically genrate proxy classes here for ServiceReference1.
Now here it generated a lot of configuration automatically. Here we specified two endpoints for HTTP protocol or for the NetTcp protocol and we get two bindings like this:
Step 12
Now for this project we will add a webform.
Now write the following code here:
- <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="HelloWebClient.WebForm1" %>
-
- <!DOCTYPE html>
-
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head runat="server">
- <title></title>
- </head>
- <body>
- <form id="form1" runat="server">
- <div style=>
- <asp:TextBox ID="TextBox1" runat="server">
- </asp:TextBox><asp:Button ID="Button1" runat="server" Text="Get Message" />
- <br />
- <asp:Label ID="Label1" runat="server" Font-Bold="true"></asp:Label>
- </div>
- </form>
- </body>
- </html>
Step 13
Now at the design mode we click on the Button and write some code here:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.UI;
- using System.Web.UI.WebControls;
-
- namespace HelloWebClient
- {
- public partial class WebForm1 : System.Web.UI.Page
- {
- protected void Page_Load(object sender, EventArgs e)
- {
-
- }
-
- protected void Button1_Click(object sender, EventArgs e)
- {
- ServiceReference1.HelloServiceClient client = new ServiceReference1.HelloServiceClient();
- Label1.Text = client.GetMessage(TextBox1.Text);
- }
- }
- }
Step 14
Now we run it and we will get an exception like this.
It occur because in the web.config we have more endpoints so we need to specify which endpoint to use. We specified the endpoint configuration name in the client constructor with the following code.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.UI;
- using System.Web.UI.WebControls;
-
- namespace HelloWebClient
- {
- public partial class WebForm1 : System.Web.UI.Page
- {
- protected void Page_Load(object sender, EventArgs e)
- {
-
- }
-
- protected void Button1_Click(object sender, EventArgs e)
- {
- ServiceReference1.HelloServiceClient client = new ServiceReference1.HelloServiceClient("BasicHttpBinding_IHelloService");
- Label1.Text = client.GetMessage(TextBox1.Text);
- }
- }
- }
Now we run and see the expected output.
Step 15
Now we will create a Windows application and use netTcpBinding here. We followed the same procedure as in the preceding. Here we create a Windows Forms application.
Now we need to add a reference of the service itself similar to the preceding procedure.
It generates a proxy class similar to the preceding and now we drag and drop the controls and design the form like this.
Step 16
Now we click on the button and write the code. Here we need to specify the endpoint we want to use. It is a formapplication so we get the endpoint name in the App.config file. A Windows application uses the TCP protocol so we use NetTcpBinding here in the following code.
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
-
- namespace HelloWindowsClient
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
-
- private void button1_Click(object sender, EventArgs e)
- {
- ServiceReference2.HelloServiceClient client = new ServiceReference2.HelloServiceClient("NetTcpBinding_IHelloService");
- label1.Text = client.GetMessage(textBox1.Text);
-
- }
- }
- }
Step 17
Now we can run the Windows application and see the output as expected.
So finally just by exposing two endpoints both of our client's requirements are met.