WCF – Merge WSDL in a single file

It can happen that old clients dislike the way WCF separate WSDL descriptors. By default, a WCF service contains the full WSDL in an external “link” specified by the wsdl:import directive. If I browse the following service http://localhost:8695/GiftMessageService.svc?wsdl i’ll get a description of the service (like ports, address) but nothing about the soap actions and messages we’ll need to use. There is the wsdl:import for that.

<wsdl:import namespace="http://tempuri.org/" location="http://localhost:8695/GiftMessageService.svc?wsdl=wsdl0" />

So, if we navigate to “http://localhost:8695/GiftMessageService.svc?wsdl=wsdl0″ we’ll get an extensive description of the operations supported, the types and so on. What WCF doesn’t allow to do is to merge these two wsdl in one file (url).  Luckly there are a few tools out there helping us, I’ve tried WCFExtras: it does a loads of feature not provided natively with WCF and one of these features is the chanche of combining the WSDL in one file only.

Download the component, add it as a reference in your project and follow the documentation, the relevant section we will need in the config is the following:

  <behavior name="Sample.WsdlSampleEndpointBehavior">
    <wsdlExtensions singleFile="true"/>

Let’s give a try by browsing the service. We’ll probably get this error:

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is: System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: WCFExtras.Wsdl.WsdlExtensions Endpoint: http://localhost:8695/GiftMessageService.svc —-> System.ApplicationException: Single file option is not supported in multiple wsdl files.

In order to fix it both the class and the contract MUST have the same namespace:

[ServiceContract(Namespace= "http://Sample/GiftMessageService")]
public interface IGiftMessageService
  string GetEncodedGiftMessageImage(int deliveryNumber, int lineItem);

  string GetEncodedGiftMessageImageWithQuality(int deliveryNumber, int lineItem, int quality);
[ServiceBehavior(Namespace = "http://Sample/GiftMessageService")]
public class GiftMessageService : IGiftMessageService



Quick note. The bindingNamespace attribute on the endpoint must also match the ServiceContract and the ServiceBehaviour namespace. This will then work!

Leave a Reply

Your email address will not be published. Required fields are marked *