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.
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.
hi sir,
ReplyDeleteHope 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
Hi Hema,
DeleteIn 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.
Hi,
ReplyDeleteWhy 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?
Venkat sir
ReplyDeleteWhile 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.
this may be because you do not run Visual Studio with administrator privileges
DeleteI think you closed servicehost console application.
DeleteKeep it in running mode will fix your issue
I am getting same error, i run run Visual Studio with administrator and opened servicehost console application.please help me
DeletePlease Check Your Console Application is running or closed it's only the solution.
DeleteHello Sir,
ReplyDeleteI am trying out this example but I get the error
base address must be absolute Uri, can you please help me with this.
Hi Sir,
ReplyDeleteI 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
Dear Mr.Venkat,
ReplyDeleteGreetings!
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
add reference of WCF service in Client appication.
ReplyDelete