Wednesday, November 14, 2012

Creating Simple WCF Service, Console Host &Console Client


Go To File->New Project and create WCF Service Application.Name it WcfTestServiceApp

In Solution Explorer you will see Service1.svc,IService1.cs & Web.Config files
Let’s poke inside IService1.cs file you will see some default code inside namespace
Remove the sample code add new code after adding new code your Iservice.cs look like
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace TestWcfServiceApp
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface ITestService
{

[OperationContract]
ComplexNumber Add(ComplexNumber c1, ComplexNumber c2);

[OperationContract]
ComplexNumber Substract(ComplexNumber c1, ComplexNumber c2);
}

// Use a data contract as illustrated in the sample below to add composite types to service operations
[DataContract]
public class ComplexNumber
{

double r = 0;
double i = 0;

[DataMember]
public double RealValue
{
get { return r; }
set { r = value; }
}

[DataMember]
public double ImaginaryValue
{
get { return i; }
set { i = value; }
}
}
}

Here you will see ITestService interface that is a service contract in short when someone want to consume our service he will no what we are offering inside our service.
We are offering functionality of adding & substracting two complex number through function
ComplexNumber Add(ComplexNumber c1, ComplexNumber c2) &
ComplexNumber Substract(ComplexNumber c1, ComplexNumber c2)

Both of these are decorated with OperationContract Attribute.
As our exposed method returning non-generic type(complex number type) to let the client communicate properly we need a datacontract.
A datacontract in simple term let client know what kind of types it needed to communicates with service.

Now Complie your wcf application.



As we changed class name in Service1.svc from default one to “TestService” we might get an error from Service1.svc markup,Right click this Service1.svc and select view markup
Modify service attribute suitably.

My MarkUp Code look like this.

<%@ ServiceHost Language="C#" Debug="true" Service="TestWcfServiceApp.TestService" CodeBehind="Service1.svc.cs" %>


Now Compile Code It should compile without any error.

Creating Host for Our WCF Service:
To host wcf service just created create we will create a console application. Name it TestWcfSrviceHost. Now add reference to DLL created in WCF Service Application from its bin folder.
Now Add a App.Config file to this host console application

Add reference to System.ServiceModel in this console application.Add Service behavior &
Service & endpoint
Note this <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> need not modified
But in second endpoint modify contract attribute to point to your interface.


In baseAddress will be the URL we like to host our service in my case it is “http://localhost:8080/Service1.svc”
My Host Console’s App.Config is listed below.

Note: When we create a client for our service, base address from Host console’s app.config get copied into client console’s app.config.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="WcfTestServiceBehaviour">
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="TestWcfServiceApp.TestService" behaviorConfiguration="WcfTestServiceBehaviour">
<endpoint address="" binding="basicHttpBinding" contract="TestWcfServiceApp.ITestService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress ="http://localhost:8080/Service1.svc"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>

Now come to Host Console’s EntryPoint i.e. Program.cs.
Add using directive needed

using System.ServiceModel;
using TestWcfServiceApp;


Now inside Main create an object of ServiceHost by passing type in my case “TestService”
Syntax for this is here
ServiceHost host = new ServiceHost(typeof(TestService));
Then start host.
My Code of Host Console’s Main Look like below listed


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using TestWcfServiceApp;

namespace TestWcfSrviceHost
{
class Program
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(TestService));
host.Open();
Console.Write("Service is up and running");
Console.Write("Wan To Shutdown this service ?,Press any key");
Console.ReadKey();
host.Close();
}
}
}

Now compile this Host Console It should compile without any errors.


Creating WCF service Client:
we have created Service Host ,Now to test service we need a service client that will call add & subtract methods of our service .
First keep running Service Host Console App.Copy Base address attributes value from Host Console’s App.config.
Inside our client console add service reference from just copied service.svc path.
Come inside Client Consoles Program.cs file.

Add using directive to added service reference namespace.In my case it is

using WcfTestServiceClient.WcfTestServiceReference;

Now inside main method of Client Console create proxy, syntax for this is.

WcfTestServiceReference.TestServiceClient proxy = new TestServiceClient();

Now you can get both Datacontract class & Service Contract Class in service reference namespace which we can use to call exposed method and retrieve correspong output.

My Client Console’s program.cs looks like below listed.Here I am calling add method exposed in wcf service

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WcfTestServiceClient.WcfTestServiceReference;


namespace WcfTestServiceClient
{
class Program
{
static void Main(string[] args)
{
WcfTestServiceReference.TestServiceClient proxy = new TestServiceClient();
double r1 = 1;
double i1 = 2;

double r2 = 3;
double i2 = 4;

WcfTestServiceReference.ComplexNumber c1 = new WcfTestServiceReference.ComplexNumber();
c1.RealValue = r1;
c1.ImaginaryValue = i1;

WcfTestServiceReference.ComplexNumber c2 = new WcfTestServiceReference.ComplexNumber();
c2.RealValue = r2;
c2.ImaginaryValue = i2;

WcfTestServiceReference.ComplexNumber result = new WcfTestServiceReference.ComplexNumber();
result = proxy.Add(c1, c2);

Console.WriteLine("Real Value=" + result.RealValue.ToString());
Console.WriteLine("Imaginary Value=" + result.ImaginaryValue.ToString());
Console.ReadKey();
}
}
}

My Client Console application’s App.Config is listed below.Actually we do not need to modify our Client console’s App.Config for this article,just listed so that it can help you to debug in case any error occurs.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ITestService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8080/Service1.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_ITestService" contract="WcfTestServiceReference.ITestService"
name="BasicHttpBinding_ITestService" />
</client>
</system.serviceModel>
</configuration>


If you have any problem while following this article to get wcf service up & running kindly let me know.
WCF is very vast topics we need to delve inside it deeply to master,this article is just basic stuff.

No comments:

Post a Comment