WCF - Windows Communication Foundation - Part 02
Hi all,
Link to: page 1, page 2
As promised I am going to write the second part of my first experience with WCF.
Just to quickly recap in the first article I was trying to write a simple WCF self host client/server solution. I had made a console application in visual studio 2008. This app would demostrate the A, B, C's (address, bindings and contract) that are required when doing WCF work.
So...now I have a service running somewhere. If however I am unable to find it, how will I ever be able to write some client code to use it's functionality?
In this article I am going to try to make my service 'visible' and once I am able to 'see' it I want to generate a proxy. With that proxy I will then try to make a client application (again just a simple console app) in order to call and execute the service. Let's go!
Step 1. Make my service visible.
I can make my service visible by allowing clients to read the metadata that my service can expose. There are most certainly circumstances where you would not want to expose your service to whole world but I have a simple case here and I am assuming it's ok. By default a service will not expose any metadata, I will thus have to expressly turn it on.
- I will need to add a new reference: System.ServiceModel.Description; This will give me access to some classes that I will need to expose metadata.
- add some more code:
ServiceMetadataBehavior beh = new ServiceMetadataBehavior(); // define a new metadata behavior
beh.HttpGetEnabled = true; // set it to true
sh.Description.Behaviors.Add(beh); // add it to my descriptions - Here is how my whole service looks:
using System;
using system.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.RunTime.Serialization;
namespace NoGiWCFServices
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(“Starting the WCF service….”);
// A address
string uri = “https://localhost:8001”;
Uri baseuri = new Uri(uri);
// B binding
WSHttpBinding binding = new WSHttpBinding();
// C contract
ServiceHost sh = new ServiceHost(typeof(IOrder), new Uri[] {baseuri});
// metadata behavior
ServiceMetadataBehavior beh = new ServiceMetadataBehavior();
beh.HttpGetEnabled = true;
sh.Description.Behaviors.Add(beh);
// Open the host
sh.Open();
Console.WriteLine(“The WCF service has started (Please press Enter to exit)….”);
Console.ReadLine();
sh.Close();
}
}
[ServiceContract(Namespace = https://nogi.com/services/OrderingService)]
public interface IOrder
{
[OperationContract()]
OrderResponse ProcessOrder(OrderRequest request);
}
public class OrderService : IOrder
{
public OrderResponse ProcessOrder(OrderRequest request)
{
Console.WriteLine(“Order Received, Contacting ERP Fulfillment system….”);
OrderResponse response = new OrderResponse();
response.OrderId = request.RequestId;
response.ResponseMessage = request.Data + “ Received”;
return response;
}
}
[DataContract(Namespace = https://nogi.com/services/OrderingServiceData)]
public class OrderRequest
{
[DataMember]
public string RequestId;
[DataMember]
public string Data;
}
[DataContract(Namespace = https://nogi.com/services/OrderingServiceData)]
public class OrderResponse
{
[DataMember]
public string OrderId;
[DataMember]
public string ResponseMessage;
}
}
Step 2. Generate a proxy.
So….now I have created a service and via self-hosting I am letting it run within a console application (C#). I need a way to call to that service and find out what it can do for me. I had placed my application within the following directory: C:\projects\WCF\NoGiDotCom\ NoGiWCFServices. If I navigate to that folder now I can find a bin folder I should be able to find a debug folder (bin\Debug) and within that there should be a NoGiWCFServices.exe. If I had had a configuration file then there would have also been a NoGiWCFServices.exe.config file. This is interesting later when I want to do my WCF with configuration files instead of hardcoding the information. If I double click the exe (NoGiWCFServices.exe) and console window should open and display messages:
Starting the WCF service….
The WCF service has started (Please press Enter to exit)….
As long as that browser window is open my service is running and ready to accept messages. It is also ready to give out metadata information about itself so that I can generate a proxy file.
Though there are different methods for generating a proxy and one of the handy ways to do it is to use the SVCUTIL that comes with Visual Studio. I could also for example use IE browser to find the WSDL for me. By typing in https://localhost:8089?WSDL I am able to get the info. Please note that the port number must be there otherwise the default port 80 is used and my service is not running there!
I wanted to use the SVCUTIL too though because it’s a new feature and think it’s fun to use new gadgets. I had to make sure that I open the command prompt that is associated with the Visual Studio environment and not an ordinary windows command prompt.
After the prompt I typed: >svcutil https://localhost:8089?WSDL My command prompt then generated an OrderService.cs and an output.config file. These files were placed in my case in the C:\Program Files\Microsoft Visual Studio 9.0\VC\OrderingService.cs folder. I then had to move these files to my NoGiWCFClient folder and then add them to that project. These are all I needed for my client application to start using my services.
Now I could go back to my visual studio solution and add existing items to my NoGiWCFClient project. I added the OrderingService.cs and the output.config. The output.config needed to be renamed to App.config.
Step 3. Build a client app that uses the proxy to use the service.
Now I was ready to the next big step…add some code and call the service!
In my NoGiWCFClient I needed to add 2 references otherwise I would get compile errors. Those references are as before, the System.ServiceModel and the System.Runtime.Serialization.
The next step was amazingly simple to get the client to talk to the service. I opened the Program.cs file (it should be empty as I have not added any code to it yet) and add a new reference within the “using” section. This was: using nogi.com.services;
Within the static void Main(string[] args) method I had to add just a few lines as follows:
class Program
{
static void Main(string[] args)
{
nogi.com.services.OrderingServiceData.OrderRequest req = new
nogi.com.services.OrderingServiceData.OrderRequest();
nogi.com.services.OrderingServiceData.OrderResponse resp = new
nogi.com.services.OrderingServiceData.OrderRequest();
OrderClient client = new OrderClient();
resp = client.ProcessOrder(req);
Console.WriteLine(“The service was called and responded with: “ + resp.Data);
Console.ReadLine();
}
}
Step 4. Fire it up!
In order to test I then navigated to my self-hosted service: C:\projects\WCF\NoGiDotCom and found my service executable: NoGiWCFServices.exe. It should start up, a command window should stay open and display the message: “The WCF service has started (Please press Enter to exit)…”.
Once I returned to my Visual Studio project I could right click on the NoGiWCFClient project and select “Debug” and then “Start new instance”. A second command window opened (from my client) and displayed the text that “The service was called and the response was: Hello World”. Noteworthy also is that in the Service window a new message appeared: “Order request received:” and if I ran the client again (whilst letting the service running) another request received message would appear.
Wow, that was my first WCF client / service application! Whew, I think I need a coffee break now. ;p