BizTalk and WCF: Consuming a WCF Service, Part 1 – A Look at the Service to be Consumed
I thought I would do a series of posts on BizTalk and Windows Communication Foundation (WCF).
The main aim of this post is to cement my experiences so far exposing and consuming WCF services using BizTalk.
First up (and the focus of this post) is a look at a (very simple) WCF service that will be hosted in IIS. Further posts will detail how the service can be consumed using BizTalk and the tools available, error handling and recovery and monitoring.
What’s WCF you may ask? Further information/background is available here. In a nutshell, it is Microsoft’s implementation of remote communication specifications maintained by groups such as the World Wide Web Consortium (W3C) and the Web Services Interoperability Organization (WS-I).
The RandomPresent WCF Service
Yes, you read correctly…! The purpose of my WCF service is to return a random present (gift) to the client application.
As per Microsoft recommended best practice, the service contract is exposed to the outside world via an interface:
It’s possible to expose a class by applying attributes directly to the class (the attributes define the service’s runtime behaviour). However by exposing the interface to the outside world (i.e. the WSDL will map to the interface) it is possible to change how the service is implemented without necessitating modifications to the WSDL. Changing the WSDL (a file that describes the functionality of a web service) would necessitate clients downloading the WSDL and updating their proxy code accordingly. So using an interface provides a level of abstraction between the specification of the service and how the service is actually implemented, thus protecting clients from any changes to the implementation of the service.
This is the class implementation:
Here are a few notes/pointers on the most interesting aspects of this interface and it’s implementation:
- Note the inclusion of the System.ServiceModel namespace – this contains all the WCF types
- Note that I have specified a namespace for some attributes – this is crucial for a professional looking WCF service! If a namespace is not explicitly specified like this, the WSDL exposed by WCF to the outside world will contain the default namespace http://tempuri.org
WCF services can be hosted in numerous ways – for the purposes of this demo, I will host my service in IIS 8. I did this by creating a new application via IIS manager and pointing it directly to my .cs files – this is OK for a development environment but in a Production environment, you would point to an assembly.
In the root of my IIS application I created a Service.svc file, which represents my WCF endpoint and a Web.config file.
My Service.svc file looks like this:
Note that the service attribute points to the implementation of the service using the full namespace and class name. If you attempt to specify the interface in your .svc file, you will receive the following error when you attempt to view your service: ServiceHost only supports class service types.
Here is the contents of my web.config file:
A few items of interest here that I will summarise:
- Two endpoints have been specified for my service: a wsHttpBinding endpoint and a MEX endpoint. The wsHttpBinding endpoint supports the WS-* specifications which defines a common standard for remote client communication. MEX stands for “metadata interchange” so it describes how a client can communicate with the service using a WSDL file exposed to the outside world by the service (meta in this context means “about” so metadata means “data about data”).
- Note that a behaviour has been specified in the <behaviors> section that enables service metadata to be downloaded via a HTTP GET. So this enables a WSDL file to be downloaded for my service (using a web browser, for example)
- And lastly, to enable me to call my service using SOAPUI, I had to add specific details about security for my endpoint, in a <wsHttpBinding> section. So this is WS-Security configuration for my service.
Now if browse to my service using a web browser, the following web page is displayed with details about the service:
This page nicely describes how to create a proxy class for this service with help from the svcutil.exe tool, a link to a WSDL that describes the functionality of the service and then example code showing how to invoke the proxy class. However, we will be calling the service from BizTalk so won’t be requiring this information (except the handy link to the WSDL).
Finally, SOAPUI is a great tool (although sometimes a bit of a fiddle to work with WCF) for testing a service.
Invoke your web service by pointing SOAPUI to the service WSDL:
- Right click on the “Projects” node and select “New soapUI project”
- In the “New soapUI Project” dialogue box, add the location of the service WSDL and ensure that the “Create Requests” check box is ticked (this will create a sample request that can be used to invoke and test the service):
- Invoke the service by double clicking on the request and click on the green arrow to submit the request to the service. On the “WS-Addressing” tab you will need to ensure that “WS-Addressing” is enabled and that the “Add default wsa:To” is ticked. This is because the service implements wsHttpBinding, as described previously, which implements WS-Addressing (part of the WS-* specifications):
So this introduces a test WCF service that needs to be consumed by BizTalk, which will be the topic of my next post…