Previous posts in this series:
Working with WCF: Part One – Introduction and Your First Service
Working with WCF: Part Two – Your First Host and A Bit About Configuration
We’ve got a service. We’ve got a host. But that’s all pointless without someone to use it.
A Tale of Three Clients
As with almost everything in WCF, you have several options about how you want to consume your service before you even start to talk about things like transport or security. As expected there are benefits and draw backs to each of the approaches. We’ll take a look at two of them in the post. In the next post we’ll take a look at the third method and take a quick lap around the WCF configuration editor.
Looking behind the curtain, all three of these approaches have the same plumbing and parts; we are creating a proxy class to represent our service. The proxy abstracts all the mechanics of communicating with the service over the wire so we don’t have to worry about that. This proxy will rely on configuration of some sort. Normally this can be done with a *.config file of some sort (as we did in the last installment) although it is possible to configure services and clients with code. We’ll take a look at this at another time. Finally, if your service relies on any complex types, these will need to be defined on the client side as well. I’ll demonstrate this in an upcoming post where I explain Data and Message Contracts.
Away we go!
The Easy
The easiest way to consume a WCF service from a .NET project is to add it as a service reference. To do this we are going to add a console application to our solutions called WebBagles.Client.Easy. Your project should have three projects now:
The idea behind this approach is that services are analogous to assemblies; you should be able to reference them and use their types. Adding a service proxy in this way is almost as easy as adding an assembly reference. Right click on the WebBagels.Client.Easy project and select “Add Service Reference…”
This will open the “Add Service Reference” dialog:
The first thing we need to supply is the address of our service or at least the server it’s on. If we know that we can simply type/paste it into the Address text box and hit the Go button. Visual Studio will go out to that address and download the WSDL for the service at that address and show us a list of what’s available.
If the service is in our solution, we can click the Discover button and Visual Studio will find all the services in our solution and list them for us. Go ahead and click the Discover button now:
The first time you run this it may take several moments to complete. As you can see Visual Studio has found our bagel order service. I’ve gone ahead and expanded the Services node so that we can see that the endpoint that was found supports our IBagelOrderService service contract with our PlaceOrder operation.
Before we click OK to have Visual Studio create the proxy for us lets change the namespace to something a little more developer friendly:
That’s better! Click the OK button and let Visual Studio do it’s magic. When the dust settles you should have a new service proxy, complete with a configuration file, as part of your client application:
All that’s left is for us to write the client to call the service! Open the Program.cs file in the WebBagels.Client.Easy project. Add the following code to the Main method:
Aside from the calls to the Console class to do our screen output, we’re just creating an instance of the proxy class we generated then calling the method on it that corresponds to our service method (PlaceOrder). In this case, we don’t technically need the close since the connection to the service will be closed when the proxy object is disposed, but it’s a good habit to get into. A lot of scaling issues in WCF have been solved by finding an unclosed connection and closing it.
Let’s try it! Hit F5 to start the service host:
Now that the service is started we can start the client. In the Solution Explorer, right click on the WebBagels.Client.Easy project and under the Debug menu select Start New Instance. Our client should make a call to our service and display the result:
Simple Is Simple For A Reason
If you need to get a simple WCF client working to call a service this is a good way to do it. The simplicity does cost though. The big one being that you can’t generate proxies as part of your build process. Also, while you can create proxies that will work in most common scenarios, you lose the ability to do some “enterprisy” things, like combine data types, import of a WSDL document, specify framework version and a bunch of other things I’ll cover in my “Stupid Client Tricks” post. For now, know that for 90% of what you are doing, the simple way is a good way to go.
The Command Line
If you want to do any complex proxy generation or make the creation of the proxy a step in the build process, then you’ll want to use the .NET command line utility SVCUTIL to generate your proxy. While “Add Service Reference” is centered around simple creation of a proxy and configuration, SVCUTIL allows some other more advanced functionality for things like combining common types from difference services, managing service namespaces and importing/exporting WSDL. Today we’re just going to use it to make a proxy.
Create a new console application project called WebBagels.Client.SVCUTIL. Your solution should like something like this:
Next fire up the Visual Studio command prompt. You specifically want this VS one as it will already have the location of SVCUTIL in the path. SVCUTIL will go out to your service to download the WSDL, so you’ll want to make sure your service is running. Right click on the WebBagels.Host project, and select Debug | Start New Instance. You’ll need the location of the service for SVCUTIL to download from, so copy the address of your service out of the hosts config file.
Once you’ve done all that, go to the command window you’ve opened and change directory till you get to the directory for the WebBagels.Client.SVCTUIL project.
OK, we’re FINALLY ready to generate our proxy!
Enter the following command into the command line. Don’t press enter yet!
Pretty, huh?
SVCUTIL has a ton of switches to customize how it works. The three you see here are the ones you’ll use most of the time. The “/out” switch allows you to specify the name of your proxy code file. In this case it will create a file called proxy.cs. If you leave this it will try to derive a name based on the service you are targeting. This can get ugly. It can also change if the people developing the service change the WSDL in certain ways. So I just get in the habit of always setting it. The “/l” switch is shorthand for “/language” and tells SVCUTIL (in this case) to create our proxy as a C# file, which is the default if you don’t specify. You can have it generate VB by using (you guessed it!) VB as your parameter. Finally, the “/config” switch tells SVCUTIL what to call the configuration file. Some developers like to keep their service configurations in separate files, and this makes it easy.
OK, hit the Enter key!
SVCUTIL will fire up, download the WSDL from your service (you remembered to start it, right?) and create your proxy and configuration files. The result should look something like this:
Go ahead and close the command window, shut down your service host and go back to Visual Studio.
Unlike “Add Service Reference” this process did not add a reference to System.ServiceModel to our client application. Go ahead and do that now.
Almost there. Right click on the WebBagels.Client.SVCUTIL project and select “Add | Existing Item… “ from the menu. Visual Studio will open the file dialog, and it should already be pointed to your project directory. Change the file type to “All files” and select the proxy.cs file and the app.config file:
Click the Add button. The files should be added to your project:
FINALLY we get to write some code! Open up the Program.cs file.
Even though we used a different process to create the proxy the procedure to call it is pretty much the same; we create an instance of the proxy object and call the methods on it:
You’ll notice that the name of the client class is different. Without telling it otherwise, SVCUTIL will take the name of the service and append “Client” to create the proxy class. This will be fine 99% of the time. If you’re ever in doubt about what SVCUTIL ended up naming your proxy class, don’t be afraid to crack up the proxy.cs class and take a look. It’s just C# code after all.
Let’s test it out. Using the same procedure above, start the service and once that’s humming along, fire up the WebBagels.Client.SVCUTIL project:
And there you go!
Until next time…
We covered a lot in this post. If you stuck it through to the end good for you! In the next post I’ll show you yet one more (and some would say the best) way of creating a WCF proxy and show you an easy way to edit those nasty configuration files.
See you then!
Print | posted on Friday, April 02, 2010 9:07 AM