Support us .Net Basics C# SQL ASP.NET ADO.NET MVC Slides C# Programs Subscribe Buy DVD

Part 4 - WCF service implementing multiple service contracts

Suggested Videos
Part 1 - Introduction to WCF
Part 2 - Creating a remoting service and a web service
Part 3 - Creating a wcf service



In this video, we will discuss 
1. How a single WCF service can implement multiple service contracts and then
2. Expose each service contract using a different endpoint

Let's understand this with an example.



Creating a WCF service that implements multiple contracts
1. Create a new class library project with name = CompanyService
2. Delete Class1.cs file that is auto-generated
3. Add a new WCF service with name = CompanyService. This should generate CompanyService.cs and ICompanyService.cs files.
4. Copy and paste the following code in ICompanyService.cs file
using System.ServiceModel;
namespace CompanyService
{
    [ServiceContract]
    public interface IMyCompanyPublicService
    {
        [OperationContract]
        string GetPublicInformation();
    }

    [ServiceContract]
    public interface IMyCompanyConfidentialService
    {
        [OperationContract]
        string GetCofidentialInformation();
    }
}
5. Copy and paste the following code in CompanyService.cs file
namespace CompanyService
{
    public class CompanyService : IMyCompanyPublicService, IMyCompanyConfidentialService
    {
        public string GetPublicInformation()
        {
            return "This is public information and available over HTTP to all general public outside the FireWall";
        }

        public string GetCofidentialInformation()
        {
            return "This is confidential information and only available over TCP behind the company FireWall";
        }
    }
}

Hosting the WCF service using a console application.
1. Right click on CompanyService solution in Solution Explorer and add a new Console Application project with name = CompanyServiceHost
2. Add a reference to System.ServiceModel assembly and CompanyService project
3. Right click on CompanyServiceHost project and add Application Configuration File. This should add App.config file to the project. Copy and paste the following XML. 
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="CompanyService.CompanyService" behaviorConfiguration="mexBehaviour">
        <endpoint address="CompanyService" binding="basicHttpBinding" contract="CompanyService.IMyCompanyPublicService"></endpoint>
        <endpoint address="CompanyService" binding="netTcpBinding" contract="CompanyService.IMyCompanyConfidentialService"></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>
4. Copy and paste the following code in Program.cs file
using System;
namespace CompanyServiceHost
{
    class Program
    {
        static void Main()
        {
            using(System.ServiceModel.ServiceHost host = new 
                System.ServiceModel.ServiceHost(typeof(CompanyService.CompanyService)))
            {
                host.Open();
                Console.WriteLine("Host started @ " + DateTime.Now.ToString());
                Console.ReadLine();
            }
        }
    }
}

Build the solution. Set CompanyServiceHost as startup project and run it by pressing CTRL + F5 keys.

Now lte's build a web application that is going to consume the WCF service.
1. Create a new asp.net empty web application and name it CompanyClient
2. Right click on References folder and select Add Service Reference option. In the address textbox type http://localhost:8080/ and click on GO button. In the namespace textbox type CompanyService and click OK. This should generate a proxy class to communicate with the service.
3. Add a new webform. Copy and paste the following HTML in WebForm1.aspx
<div style="font-family:Arial">
    <table style="border:1px solid black">
        <tr>
            <td>
                <asp:Button ID="Button1" runat="server" Text="Get Public Information" 
                    onclick="Button1_Click" Width="300px" />
            </td>
            <td>
                <asp:Label ID="Label1" runat="server" Font-Bold="true"></asp:Label>            
            </td>
        </tr>
        <tr>
            <td>
                <asp:Button ID="Button2" runat="server" Text="Get Confidential Information" 
                    onclick="Button2_Click" Width="300px" />
            </td>
            <td>
                <asp:Label ID="Label2" runat="server" Font-Bold="true"></asp:Label>            
            </td>
        </tr>
    </table>
</div>
4. Copy and paste the following code in WebForm1.aspx.cs file
protected void Button1_Click(object sender, EventArgs e)
{
    CompanyService.MyCompanyPublicServiceClient client1 = new
        CompanyService.MyCompanyPublicServiceClient("BasicHttpBinding_IMyCompanyPublicService");
    Label1.Text = client1.GetPublicInformation();
}

protected void Button2_Click(object sender, EventArgs e)
{
    CompanyService.MyCompanyConfidentialServiceClient client2 = new 
        CompanyService.MyCompanyConfidentialServiceClient("NetTcpBinding_IMyCompanyConfidentialService");
    Label2.Text = client2.GetCofidentialInformation();
}

Here is the requirement
1. MyCompanyPublicService should be available to everyone behind and outside the firewall
2. MyCompanyConfidentialService should be available only with in the company behind the firewall. 

But with the client web application we are able to create proxy classes of both the services and invoke both the methods. That is because in our case we are having both the client and the service running on the same machine. When it comes to clients outside the firewall, they will be able to create proxy classes of both the services, but when they attempt to invoke the MyCompanyConfidentialService method they would get an exception.

Is it possible for a WCF service to implement multiple service contracts?
Yes, we make the service class implement multiple service interfaces, and then expose each service using a different endpoint.

wcf tutorial

11 comments:

  1. hi sir,
    Hope you are doing good. i would like to thank for your help from the bottom of my heart and one doubt have , in this example you did not mention any mex endpoint .but in previous example you mentioned mex end point adress .please clarify me on this when can we use mex endpoint . In a general application , how many mex end points we can write

    ReplyDelete
    Replies
    1. Hi Hema,

      In WCF,Meta data can be exposed in 2 ways.
      1.WSDL - Default format and it doesn't support non http protocols.
      2.Mex - New improved version and supports non http protocols and it has some additional security features.
      It will expose metadata via wsdl through the defautl url, even if you don't have defined a mex endpoint for your service

      Hope it helps.

      Delete
  2. Hi,
    Why are you creating a class library and then a console application to host that service.What is the advantage of creating a WCF service like this rather than directly creating a WCF application?

    ReplyDelete
  3. Venkat sir

    While Consuming service through Client proxy application,i had an error please explain why?
    There was an error downloading 'http://localhost:8099/_vti_bin/ListData.svc/$metadata'.
    Unable to connect to the remote server
    No connection could be made because the target machine actively refused it 127.0.0.1:8099
    Metadata contains a reference that cannot be resolved: 'http://localhost:8099/'.
    There was no endpoint listening at http://localhost:8099/ that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
    Unable to connect to the remote server
    No connection could be made because the target machine actively refused it 127.0.0.1:8099
    If the service is defined in the current solution, try building the solution and adding the service reference again.

    ReplyDelete
    Replies
    1. this may be because you do not run Visual Studio with administrator privileges

      Delete
    2. I think you closed servicehost console application.
      Keep it in running mode will fix your issue

      Delete
    3. I am getting same error, i run run Visual Studio with administrator and opened servicehost console application.please help me

      Delete
    4. Please Check Your Console Application is running or closed it's only the solution.

      Delete
  4. Hello Sir,

    I am trying out this example but I get the error

    base address must be absolute Uri, can you please help me with this.


    ReplyDelete
  5. Hi Sir,

    I am getting error on clicking on second button. error message is shows:
    "An exception of type 'System.ServiceModel.Security.SecurityNegotiationException' occurred in mscorlib.dll but was not handled in user code

    Additional information: A call to SSPI failed, see inner exception."

    Can u please help me ASAP

    ReplyDelete
  6. Dear Mr.Venkat,

    Greetings!

    You are doing great to Society. God bless you.

    I have tried the sample by following the steps in your WCF blog and also compared with your WCF video4. I did it without any alterations in naming the items.

    But, finally when i running web app, I am getting 6 errors in Reference.cs file

    The type name 'CompanyService' does not exist in the type 'CompanyServiceClient.CompanyServiceClient'

    Please guide me in this case. I have cross checked the each line of my code with your blog and video.

    Thanks in advance

    ReplyDelete

If you like this website, please share with your friends on facebook and Google+ and recommend us on google using the g+1 button on the top right hand corner.