Consuming a WCF service

 

Adding references to WCF services is trivially easy with Visual Studio 2008, but if you're still working with 2005 there are a few things that need to be considered when referencing WCF services instead of using Add Web Reference

The following step-by-step is meant to help particularly those who have not developed WCF services but just need to consume them.  It applies to both, VS 2005 and VS 2008.

Prerequisite installs for Visual Studio 2005

If you are in a library, console, or Windows forms project, you should be seeing an Add Service Reference item in your project's context menu. If you don't see this, you are missing some prerequisites. Download and install the following packages:

  1. .NET Framework 3.0 Redistributable
    These are the libraries that contain the WCF namespaces, such as System.ServiceModel and System.Runtime.Serialization. This package also contains WF and WPF runtime libraries.
  2. Visual Studio 2005 "Orcas" Extensions
    The WCF and WPF (Windows Presentation Foundation) extensions that enable IDE integration into Visual Studio 2005.
  3. .NET Framework 3.0 SP1

You should not have to install the Windows SDK (it's a huge download) to enable IDE integration, even if the Extensions install complains that it's not present. Ignore this message if you are only interested in consuming WCF services.

VS 2005 web site projects

In Visual Studio 2005, you will not see an Add Service Reference command in web site projects, even after installing above prerequisites.  Apparently this was an oversight and didn't quite make it into the Extensions CTP release, because VS 2008 has this option.  To work around this you have two options:

  • Create a class library project, add it to your solution, and create your service references there. You will need to transfer generated app.config sections to your web.config (see below). 
  • Generate your proxy classes and configurations using svcutil.exe utility, and include the generated files in the web site project.
Adding the Service Reference
  1. Test the service from your web browser. Navigate to the .svc file. If everything checks out, copy the URL from the Address bar.
  2. Right-click on the project in the Solution Explorer window and choose Add Service Reference. In VS 2005, you'll see the following dialog.
    Add Service Reference Dialog
  3. Enter (paste) the URL to your service's .svc file. (.svc?wsdl works as well)
  4. Give the service a short but descriptive name. This will become a part of your proxy class' namespace (more about that later).

In VS 2008, you see more a bit more information about the service, plus you get a lot more control over generated data types through the Advanced options dialog:
Ref2008_Advanced

This will generate several files. What files are generated differs between VS 2005 and VS 2008, and between non-web and web projects in VS 2008. Essentially you will come out of this operation with a proxy class and some configuration values.

The client proxy class

When you expand the tree under the service reference, you'll find a .cs file (VS 2005) that contains your proxy class. Note that it adopted the root namespace of the project it was generated in. I mention this because this is an important difference from how .asmx references were created, and also from how svcutil.exe creates your proxy.

proxy namespace

To instantiate the proxy class, use the following naming pattern:


ProjectRootNamespace.ServiceReferenceName.ServiceNameClient myServiceClient =
               new ProjectRootNamespace.ServiceReferenceName.ServiceNameClient("EndpointConfigurationName");


Notice the class name ends in Client.  Where do you get the EndpointConfigurationName from?  Glad you asked. Read on...

Configuration considerations

Besides generating a proxy class, Visual Studio's also writes a section into your .config file when you Add a Service Reference. This section is bounded by


<system.serviceModel>  </system.serviceModel>


tags. If you generated the proxy in a class library project, you will have to copy this section to the executing assembly project's .config file. 

appconfig

One of the nice advantages of using a service reference over a web reference is that you have complete control over the channel stack, security, protocols, etc. through configuration. The generated configuration mimics the service's configuration on the server. The things to understand are:


  • Endpoints, in the <client> node, consist of an Address, a Binding and a Contract.  A service can expose multiple endpoints, but since you are pointing your reference tool at a specific endpoint, and not the service directly, you will only ever get one from the tool. The endpoint has a name, which you need when instantiating a the client proxy (so EndpointConfigurationName above would be replaced with MyWCFServiceBasicHttp in this example).
  • The Binding defined in the <bindings> node defines the communication patterns. It is referenced by the endpoint with the bindingConfiguration attribute.
  • The Contract defined by a fully qualified interface name. Notice that the namespace is NOT the namespace defined in the service, but the one your proxy class resides in. This may be confusing especially if you also developed the service.  If you instantiate your proxy class with above example, you don't need to care about the interface .

Again, remember to copy these sections into the executing assembly's .config file!

Updating a service reference

If the service implementation changes without data- or service contract (method signature) changes, you don't need to do anything at the client. If the contract or address has changed, however, you need to re-generate your proxy and may need to update your configuration. This can also be done through the IDE. 


  • Right-click on the reference in Solution Explorer and choose Update Service Reference.
    This will also replace the .config section, regardless of server config changes or not. If you made config changes in your client config, be aware that you may end up with double entries with names such as MyWCFServiceBasicHttp1 (to use the example above). You should clean those up, or you will end up with a holy mess after a while.

If your service moved, or you want to test, say, the staging or production service, the procedure differs between VS2005 and 2008:


  • VS2005:  Open the  .map file under the service reference. It looks something like this:
    map file
    Edit the ServiceReferenceUri only, and save the .map file, and Update Service Reference as before.  You will see the EndPoint Address change automatically as the service is contacted, a new proxy is generated and the .config file is updated.
  • VS2008:  Right-click the reference in Solution Explorer and choose Configure Service Reference.  You will see the Service Reference Settings dialog (see above). Change the Address value, click OK, and everything that needs to happen happens.

Remember again, to copy the config section into your executing assembly if you are operating in a class library.

Using svcutil.exe

You can do all the above and more using the command line tool, svcutil.exe.  In VS2005, this may be your best option if you want to establish service references in a web site project.

Note that the tool resides in different locations for the different VS versions:


  • VS2005: C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\
  • VS2008: C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\

Open a command prompt, navigate to your project directory, and use this simple command line to generate a proxy and config:


"C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\svcutil.exe" http://localhost:4068/MyWCFService/Service.svc /out:MyWCFService.cs


This is the basic command line, you may want to investigate into other options for lots more control. For more information see http://msdn2.microsoft.com/en-us/library/aa347733.aspx.

Configurations will be written into an output.config file. CAUTION: If you use the /config switch, do not directly reference your application configuration file, as it will be overwritten. If you had other config sections, you have just lost them. The VS IDE is much smarter about diffing the .config files first.

Notice that the namespace of the generated proxy class is based on the service's namespace if you don't specify it explicitly through the commandline.

svcutil_namespace

Include the proxy class in your project (in a web project, in your app_code folder), and copy the config sections into the executing assembly config ... done!