views:

71

answers:

1

I'm trying to consume a .Net Web Service using perl and SOAP Lite.

When I consume the web service in a .Net client - it posts to the .asmx endpoint the following:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tns="http://mysoapnamespace.com/"
xmlns:types="http://mysoapnamespace.com/encodedTypes"&gt;
  <soap:Body>
    <tns:HellowWorld  />
  </soap:Body>
</soap:Envelope>

How can I generate that same request using SOAP Lite? I've been through a variety of SOAP Lite docs and articles with no luck. So far I have the following:

#!/usr/bin/perl
use SOAP::Lite 'trace', 'debug' ;

$api_ns = "https://mysoapnamespace.com";
$api_url = "http://mysoapnamespace/api.asmx";
$action = "HelloWorld";

  my $soap = SOAP::Lite 
   -> readable(1)
   -> uri($api_ns)
   -> proxy($api_url)
   -> on_action(sub { return "\"$action\"" }) ;


return $soap->HellowWorld();

This generates this, incorrect XML:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;
  <soap:Body>
    <HellowWorld xmlns="http://mysoapnamespace.com" xsi:nil="true" />
      </soap:Body>
</soap:Envelope>

Update:

When I post the 1st xml to my service using fiddler it returns my "Hello World" result. When I post the 2nd I get the following:

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;&lt;soap:Body&gt;&lt;soap:Fault&gt;&lt;faultcode&gt;soap:Client&lt;/faultcode&gt;&lt;faultstring&gt;System.Web.Services.Protocols.SoapException: Server was unable to read request. ---&gt; System.InvalidOperationException: There is an error in XML document (9, 6). ---&gt; System.InvalidOperationException: &lt;HellowWorld xmlns='http://mysoapnamespace.com'&amp;gt; was not expected.
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read21_HellowWorld()
   at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer28.Deserialize(XmlSerializationReader reader)
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle)
   at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()
   --- End of inner exception stack trace ---
   at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()
   at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()</faultstring><detail /></soap:Fault></soap:Body></soap:Envelope>
+3  A: 

Found the problem - the trailing slash on the namespace. .Net just figures that stuff out for your but it needs to be explicitly set in Perl. Also, figured out how to us the ns() function to add names spaces.

This will generate the correct XML.

#!/usr/bin/perl
use SOAP::Lite 'trace', 'debug' ;

$api_ns = "https://mysoapnamespace.com/";
$api_url = "http://mysoapnamespace/api.asmx";
$action = "HelloWorld";

  my $soap = SOAP::Lite 
   -> readable(1)
   -> ns($api_types,'types')
   -> ns($api_ns,'tns')
   -> proxy($api_url)
   -> on_action(sub { return "\"$action\"" }) ;


return $soap->HellowWorld();

This link was very helpful in figuring out SOAP::Lite - http://kobesearch.cpan.org/htdocs/SOAP-Lite/SOAP/Lite.pm.html

brendan
BTW, the canonical link for any CPAN module's documentation is always `http://search.cpan.org/perldoc?<module name>`, or just go to http://search.cpan.org and type in the module name into the search field. If you're *really* lazy, just google "cpan <modulename>" and you'll get the right result 99% of the time.
Ether
very cool, thanks! - definitely not a perl expert here
brendan