Each time when we want to consume a WCF service, we need to create proxy at client side. To create proxy, service must expose metadata endpoint.
Normally
- We create a WCF service
- Expose metadata endpoint
- Add service reference at client side to create the proxy.
- Using the proxy calls the service operation contracts.
Normally we call the service as
MyServiceContractClient proxy = new MyServiceContractClient();
var res = proxy.GetData(9);
console.WriteLine(res);
console.ReadKey(true);
Let us assume we want to call the service using channel without creating proxy or adding the service reference. We need to follow the below steps
Step 1
Put all the DataContract or ServiceContract in a separate DLL or class library. Add the reference of System.ServiceModel in class library. And create the service contract as below,
MyServiceContract.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace ContractDll
{
[ServiceContract]
public interface MyServiceContract
{
[OperationContract]
string GetData(int value);
}
}
Assume we have created a service library called ContractDLL
Step 2
Create a WCF Service application and implement the service contract created in step 1. For that add the reference of project created in step 1 in WCF service application.
Service1.svc.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using ContractDll;
namespace WcfService1
{
public class Service1 : MyServiceContract
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
}
Add the EndPoint in config file.
<services>
<service name ="WcfService1.Service1" >
<endpoint address ="" binding ="basicHttpBinding" contract ="ContractDll.MyServiceContract"/>
<host>
<baseAddresses>
<add baseAddress ="http://localhost:8181/Service1.svc"/>
</baseAddresses>
</host>
</service>
</services>
In above config file
- ContractDLL.MyServiceContract is name of the service contract exposed.
- There is no metadata exchange endpoint in the config file.
Full Web.Config is as below,
Web.Config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name ="WcfService1.Service1" >
<endpoint address ="" binding ="basicHttpBinding" contract ="ContractDll.MyServiceContract"/>
<host>
<baseAddresses>
<add baseAddress ="http://localhost:8181/Service1.svc"/>
</baseAddresses>
</host>
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Step 3
Create the client. We are creating a console client to consume the service with channel or without creating proxy. So follow the below steps
- Do not add the service reference.
- Add the reference of System.ServiceModel.
- Add the reference of class library created in step1.
Now we need to
- Create a ChannelFactory
ChannelFactory factory = null;
- Create a binding of the type exposed by service
BasicHttpBinding binding = new BasicHttpBinding();
- Create EndPoint address
EndPointAddress address = new EndPointAddress("http://localhost:4684/Service1.svc");
- Pass Binding and EndPoint address to ChannelFactory
factory = new ChannelFactory(binding,address);
- Now create the channel as below ,
MyServiceContract channel = factory.CreateChannel();
- Call the service method on this channel as below ,
string returnmessage = channel.GetData(9);
So full code of client will be like below
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using ContractDll;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ChannelFactory factory = null;
try
{
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress address = new EndpointAddress("http://localhost:4684/Service1.svc");
factory = new ChannelFactory(binding, address);
MyServiceContract channel = factory.CreateChannel();
string resturnmessage = channel.GetData(9);
Console.WriteLine(resturnmessage);
Console.ReadKey(true);
}
catch (CommunicationException)
{
if (factory != null)
factory.Abort();
}
catch (TimeoutException)
{
if (factory != null)
factory.Abort();
}
catch (Exception ex)
{
if (factory != null)
factory.Abort();
Console.WriteLine(ex.Message);
}
Console.WriteLine("Proxy closed");
Console.ReadKey(true);
}
}
}
And we will get output as
