In Windows Communication Foundation, contracts provide interoperability. They need to communicate with the client. Sometimes in our mind the question arise; can we implement multiple service contract in WCF service?
And the answer is, Yes we can. Service class implement multiple service interfaces, and then expose each service using a different endpoint.
This article explains how to do multiple service contracts in a WCF Service.
Multiple Service Contracts in WCF
So let's create multiple service contracts in WCF.
- Open Visual Studio as Adminitrator.
- "File" -> "New" -> "Project...".
- Select Class Library, Click Ok.
- Remove Class1.cs that is auto generated from the solution in Solution Explorer.
- Then seelct "Add" >> "New Item" >> "WCF Service" then provide the name "MultipleService.cs".
- Click the Add Button.
Now we have one interface IMultipleService.cs and one class file MultipleService.cs. Now when you open the IMultipleService.cs file it looks like that. (See the following code).
IMultipleService.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.Serialization;
- using System.ServiceModel;
- using System.Text;
-
- namespace MultipleServiceContractDemo
- {
- [ServiceContract]
- public interface IMultipleService
- {
- [OperationContract]
- void DoWork();
- }
- }
In the code above you can see that here is only one service contract. Now in this service interface we will add two Service Contracts.
- IMultiplePublicService: For those, who are outside and inside of the firewall. We use here httpBinding.
- IMultipleConfidentialService: For those, who are inside of the firewall. We use here netTcpBinding.
Now it is time to change the code above in both files.
IMultipleService.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.Serialization;
- using System.ServiceModel;
- using System.Text;
-
- namespace MultipleServiceContractDemo
- {
- [ServiceContract]
- public interface IMultiplePublicService
- {
- [OperationContract]
- string GetPublicInformation();
- }
-
- [ServiceContract]
- public interface IMultipleConfidentialService
- {
- [OperationContract]
- string GetConfidentialInformation();
- }
- }
MultipleService.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.Serialization;
- using System.ServiceModel;
- using System.Text;
-
- namespace MultipleServiceContractDemo
- {
- public class MultipleService : IMultiplePublicService, IMultipleConfidentialService
- {
- public string GetPublicInformation()
- {
- return "I am watching Public Information over HTTP.";
- }
-
- public string GetConfidentialInformation()
- {
- return "I am watching Confidential Information over TCP.";
- }
- }
- }
Did you notice in the code above here I use multiple interfaces and implement the methods of these interfaces.
Now to host this service.
Now add a new console application project into the same solution and click the OK button.
Now click "Add Reference" then select the Add Wcf Project reference, click OK.
Now again Add Reference, this time we will add System.ServiceModel. Just click on Add Reference then click on the .Net Tab and select System.ServiceModel then click OK.
Now we will add an App.Config for this project, so add a new App.Config file.
App.Config
- <?xml version="1.0" encoding="utf-8" ?>
- <configuration>
- </configuration>
This is the part where we define the service and the service behaviour for the service. See the following code.
- <?xml version="1.0" encoding="utf-8" ?>
- <configuration>
- <system.serviceModel>
- <services>
- <service name="MultipleServiceContractDemo.MultipleService" behaviorConfiguration="mexBehaviour">
- <endpoint address="MultipleServiceContractDemo" binding="basicHttpBinding" contract="MultipleServiceContractDemo.IMultiplePublicService"></endpoint>
- <endpoint address="MultipleServiceContractDemo" binding="netTcpBinding" contract="MultipleServiceContractDemo.IMultipleConfidentialService"></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>
Understand the code
In the code above we have 2 sections, one is <system.ServiceModel> and the other is the <behaviors> section. So let's understand the code, because this is very important.
- <service name="MultipleServiceContractDemo.MultipleService" behaviorConfiguration="mexBehaviour">
Here we describe the name of the service and behaviorConfiguration. So in the code above we have the MultipleServiceContractDemo namespace and in this namespace we have the MultipleService class file. In behaviourConfiguration we define the name of ServiceBehaviour that we defined in the <serviceBehaviour> Section.
- <endpoint address="MultipleServiceContractDemo" binding="basicHttpBinding" contract="MultipleServiceContractDemo.IMultiplePublicService"></endpoint>
- <endpoint address="MultipleServiceContractDemo" binding="netTcpBinding" contract="MultipleServiceContractDemo.IMultipleConfidentialService"></endpoint>
Here we define an endpoint for our service where address is the network address of the service, binding specifies the transport protocol (HTTP, TCP and so on) selected for the service and contract is the interface the service implements.
So, what is the Binding?
The binding is an attribute of an endpoint and it lets you configure the transport protocol, encoding and security requirements.
Types of WCF Binding
- BasicHttpBinding: Basic web service communication. Exposes WCF services as legacy ASMX web services. Used for interoperability. No security by default.
- WSHttpBinding: Web services with WS-* support. Supports transactions and reliable messaging.
- 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 the 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.
- <host>
- <baseAddresses>
- <add baseAddress="http://localhost:8080"/>
- <add baseAddress="net.tcp://localhost:8090"/>
- </baseAddresses>
- </host>
So in the end point section we define two types of bindings and now in the <host> section we define the <baseAddress> baseaddress is the path. Using this address the user can consume our services. In this example we have the following two types of bindings so here we provide two addresses for both bindings.
- <behaviors>
- <serviceBehaviors>
- <behavior name="mexBehaviour">
- <serviceMetadata httpGetEnabled="true"/>
- </behavior>
- </serviceBehaviors>
- </behaviors>
The code above is the <behaviors> section where we define the behaviour name and <serviceMetadata httpGetEnabled=”true”>. When our user consumes our service, that time each service provides a WSDL document, in this document the user can understand, how many contracts are in the service and what are the datatypes of this method.
For this kind of information, we need to set the <behaviours> part.
Program.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.ServiceModel;
- namespace MyServiceHost
- {
- class Program
- {
- static void Main(string[] args)
- {
- using (ServiceHost host = new ServiceHost(typeof(MultipleServiceContractDemo.MultipleService)))
- {
- host.Open();
- Console.WriteLine("Service Starts at: "+DateTime.Now);
- Console.ReadKey();
- }
- }
- }
- }
Now the creation of the service is done. Just select our MyServiceHost Project as Set as StartupProject. And press F5.
If you open Visual Studio as Administrator, you will get this screen.
If you are getting the following error, that means you haven't opened your Visual Studio as Administrator. Close the Visual Studio, open it again with Administrator. And run the project.
Now open a new Visual Studio screen. Let's create a new project and select Empty Web Application. Now add a new WebForm.
Now add a Service Reference for our service. Right-click on the References folder and click Add Service Reference.
In the Address section type: http://localhost:8080. If you remember we provided this address in our app.config file at the base address section. This address has a WSDL document. Now one thing you need to always remember is that your service should always run, so please check currently your service is running or not.
So if you saw in the preceding screen, we have MultipeService, we have two ServiceContracts. Now click OK. Now our WSDL document should be generated.
WebForm1.aspx
- <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="CompanyClient.WebForm1" %>
-
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head runat="server">
- <title></title>
- </head>
- <body>
- <form id="form1" runat="server">
- <table>
- <tr>
- <td>
- <asp:Button ID="bttn_Public" runat="server" Text="Get Public Service" OnClick="bttn_Public_Click" />
- </td>
- <td>
- <asp:Label ID="lblPublic" runat="server" Text=""></asp:Label>
- </td>
- </tr>
- <tr>
- <td>
- <asp:Button ID="bttn_Confidential" runat="server" Text="Get Confidential Service"
- OnClick="bttn_Confidential_Click" />
- </td>
- <td>
- <asp:Label ID="lbl_Confidential" runat="server" Text=""></asp:Label>
- </td>
- </tr>
- </table>
- </form>
- </body>
- </html>
Webform1.aspx.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.UI;
- using System.Web.UI.WebControls;
-
- namespace MySerivieConsume
- {
- public partial class WebForm1 : System.Web.UI.Page
- {
- protected void Page_Load(object sender, EventArgs e)
- {
-
- }
-
- protected void bttn_Public_Click(object sender, EventArgs e)
- {
- MyService.MultiplePublicServiceClient client = new MyService.MultiplePublicServiceClient("BasicHttpBinding_IMultiplePublicService");
- lblPublic.Text = client.GetPublicInformation();
- }
-
- protected void bttn_Confidential_Click(object sender, EventArgs e)
- {
- MyService.MultipleConfidentialServiceClient client = new MyService.MultipleConfidentialServiceClient("NetTcpBinding_IMultipleConfidentialService");
- lbl_Confidential.Text = client.GetConfidentialInformation();
- }
- }
- }
Now press F5 and run your project. If you notice when you click on both buttons, you are getting the output because currently our main service and we are consuming the service in the same machine, we are not consuming this from outside of the firewall, that's why we are getting both outputs.
I hope you enjoyed this article, for any query or suggestion, please send your comments. Thank you.