How to consume a WCF service from Perl with SOAP::Lite

Posted by adamjh on Jul 23rd, 2007

Due to the outdated state of Perl's only SOAP library and less-than-stellar documentation on Windows Communication Foundation web service interoperability, getting a Perl script to consume a WCF service sent me on a debugging adventure accompanied by a scavenger hunt for information scattered across the web.

Below are the tweaks that must be made to a new WCF service created using the "WCF Service Library" project template in Visual Studio 2008 Beta 1 ("Orcas") and an example of a how to call the service from a SOAP::Lite client script:

Step 1. Change the service endpoint binding from the default wsHttpBinding to basicHttpBinding:

    <endpoint address ="" binding="basicHttpBinding" contract="Service1.IService1" />

Step 2. Change the data contract format to RPC:

    [ServiceContract]
    [DataContractFormat(Style=OperationFormatStyle.Rpc)]
    public interface IService1
    {

Step 3. Specify an on_action() method in the SOAP::Lite client to override the default Namespace#Action with the format WCF expects:

$data = SOAP::Lite
  -> uri('http://tempuri.org/')
  -> proxy('http://localhost:8080/IService1')
  -> on_action(sub{sprintf '%sIService1/%s', @_})
  -> GetData(SOAP::Data->name('intParam' => 5))->result;

Note: If you decide to do this, you should understand the implications of changing the service endpoint binding and the data contract format.  Supporting information is available somewhere in the bowels of MSDN.

Update [Nov 5 2007]: I ran into new problems when moving from SOAP::Lite 0.55 (the highest supported in ActivePerl on Windows) to SOAP::Lite 0.69 (the latest version as of now, and running on Linux).  It seems SOAP::Lite evolved from the SOAP 1999 (1.1) to 2001 (1.2) schema, and somewhere in the mix, new conflicts arose with WCF interoperability.  After a few hours of horrid tracing and hacking, I've decided to ditch Perl and SOAP altogether for Ruby and REST.  Welcome, Adam, to the year 2007.