in reply to Re^4: SOAP::Lite, .NET, and complex structures
in thread SOAP::Lite, .NET, and complex structures

The steps I use are as follows:
  1. Publish the proper WSDL (generate with Pod::WSDL) after having annotated your (dispatchable) classes with POD as described for classes in Pod::WSDL's documentation.
  2. Please check that the generated WSDL actually contains nice-looking descriptions of your classes (properly marked as complex types).
  3. Don't try to "construct" your complex types. Use normal hash-based perl objects. Return them (or arrays of them) directly.

I'll try to find the time to put up a working example soon.

Update:

Example of annotated class:

package Wholesale::Addon; =begin WSDL _ATTR productid $int doc for attr. _ATTR name $string doc for attr. _ATTR description $string doc for attr. _ATTR price $int doc for attr. _ATTR windowIncr $int doc for attr. _ATTR computerIncr $int doc for attr. _ATTR deferred $boolean doc for attr. _ATTR addonid $int doc for attr. _ATTR added $dateTime doc for attr. _ATTR username $string doc for attr. =end WSDL =cut sub new { my $class = shift; my ($productid, $name, $description, $price, $windowIncr, $computerIncr, $deferred, $addonid, $added, $username) = @_; bless { productid => $productid, name => $name, description => $description, price => $price, windowIncr => $windowIncr, computerIncr => $computerIncr, deferred => $deferred, addonid => $addonid, added => $added, username => $username }, $class; } #... methods omitted for brevity. 1;

Example (excerpt) of complexType generated by Pod::WSDL:

<complexType name="WholesaleAddon"> <sequence> <element name="productid" nillable="true" type="xsd:int"> <wsdl:documentation>doc for attr.</wsdl:documentation> </element> <element name="name" nillable="true" type="xsd:string"> <wsdl:documentation>doc for attr.</wsdl:documentation> </element> <element name="description" nillable="true" type="xsd:string"> <wsdl:documentation>doc for attr.</wsdl:documentation> </element> <element name="price" nillable="true" type="xsd:int"> <wsdl:documentation>doc for attr.</wsdl:documentation> </element> <element name="windowIncr" nillable="true" type="xsd:int"> <wsdl:documentation>doc for attr.</wsdl:documentation> </element> <element name="computerIncr" nillable="true" type="xsd:int"> <wsdl:documentation>doc for attr.</wsdl:documentation> </element> <element name="deferred" nillable="true" type="xsd:boolean"> <wsdl:documentation>doc for attr.</wsdl:documentation> </element> <element name="addonid" nillable="true" type="xsd:int"> <wsdl:documentation>doc for attr.</wsdl:documentation> </element> <element name="added" nillable="true" type="xsd:dateTime"> <wsdl:documentation>doc for attr.</wsdl:documentation> </element> <element name="username" nillable="true" type="xsd:string"> <wsdl:documentation>doc for attr.</wsdl:documentation> </element> </sequence> </complexType>

Example of method returning a list of complex values:

package Wholesale; use Wholesale::Addon; # other methods ommitted for brevity =begin WSDL _DOC doc for method. _IN username $string doc for param. _RETURN @Wholesale::Addon doc for returnval. =end WSDL =cut sub list_attached_addons { # process arguments my $self = shift; my ($username) = @_; my @addons; # <snip> # construct a list of Wholesale::Addon objects # here using Wholesale::Addon->new(...) passing # data retrieved from the database. # </snip> return @addons; } 1;

Example (excerpts) of WSDL generated by Pod::WSDL for above method:

<wsdl:operation name="list_attached_addons" parameterOrder="username"> <wsdl:documentation>doc for method.</wsdl:documentation> <wsdl:input message="impl:list_attached_addonsRequest" name="list_at +tached_addonsRequest" /> <wsdl:output message="impl:list_attached_addonsResponse" name="list_ +attached_addonsResponse" /> </wsdl:operation> <wsdl:operation name="list_attached_addons"> <wsdlsoap:operation soapAction="" /> <wsdl:input name="list_attached_addonsRequest"> <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/enco +ding/" namespace="http://127.0.0.1:2233/Wholesale" use="encoded" /> </wsdl:input> <wsdl:output name="list_attached_addonsResponse"> <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/enco +ding/" namespace="http://127.0.0.1:2233/Wholesale" use="encoded" /> </wsdl:output> </wsdl:operation> <wsdl:message name="list_attached_addonsRequest"> <wsdl:part name="username" type="xsd:string"> <wsdl:documentation>doc for param.</wsdl:documentation> </wsdl:part> </wsdl:message> <wsdl:message name="list_attached_addonsResponse"> <wsdl:part name="list_attached_addonsReturn" type="tns1:ArrayOfWhole +saleAddon"> <wsdl:documentation>doc for returnval.</wsdl:documentation> </wsdl:part> </wsdl:message> <complexType name="ArrayOfWholesaleAddon"> <complexContent> <restriction base="soapenc:Array"> <attribute ref="soapenc:arrayType" wsdl:arrayType="tns1:Wholesal +eAddon[]" /> </restriction> </complexContent> </complexType>
That all works fine for me.

Are you doing anything terribly more complicated than that?

-David.

Replies are listed 'Best First'.
Re^6: SOAP::Lite, .NET, and complex structures
by MidLifeXis (Monsignor) on Aug 16, 2007 at 15:15 UTC

    Nope, that is pretty much it.

    One thing I did find, however, is a size issue of some sort or another. For example, this list with 9 elements is parsed correctly by the .Net WebServices Studio tool.

    But the same response with an array size of 10 returns a There is invalid data at the root level. Line 1, position 1. error from that tool. Here is the data that is returned (retrieved by sending a request by hand to the service via telnet)

    Whatever the cause, It is a little bit frustrating, to say the least :)

    I am almost to the point of tossing the .NET WebService Studio tool, except that it works with our existing production server. I will update shortly to see if a different version of Apache (the current production setup) causes this to behave.

    Update: Happens in the production version of apache as well (1.3), so it does not look like it is related to Apache. In production, the break point is going from 6 to 7 items in the array.

    Update 2: Oh yeah. I forgot to say, replace all of the localhost:80 stuff with the local server name. It gets replaced on the server side automatically.

    grrrr

    --MidLifeXis

      I haven't used that tool... only wsdl.exe

      It has worked for me thus far.

      -David