Greetings dear monks,
I'm starting using SOAP::Lite to deal with .Net clients and I'm having some confusion regarding how to deal with the design of WSDL, server and client when is necessary to use document style of XML messages.
Since .Net favor the use of document style, I created the following types in the WSDL:
<types>
<xsd:schema targetNamespace="urn:SiebelPhysician">
<xsd:complexType name="FindByRCNRequest">
<xsd:sequence>
<xsd:element name="federativeUnity" type="xsd:string"/>
<xsd:element name="regionalConcilNumber" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="FindByRCNResponse">
<xsd:sequence>
<xsd:element name="firstName" type="xsd:string"/>
<xsd:element name="lastName" type="xsd:string"/>
<xsd:element name="type" type="xsd:string"/>
<xsd:element name="status" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</types>
If I undestood correctly, to send a request I would need to create, inside the SOAP envelope, an XML with the structure defined for FindByRCNRequest. The request should include (in the HTTP header SOAPAction) the name of the method to be called.
Well, during my tests using a SOAP::Lite client, I finished with something like this:
use SOAP::Lite;
print SOAP::Lite->service('http://localhost/SiebelSOAP/SiebelPhysician
+.xsd')
->FindByRCN(
SOAP::Data->type('complex')->name('FindByRCNRequest')->value(
\SOAP::Data->value(
SOAP::Data->type('string')->name('federativeUnity')->value
+('PR'),
SOAP::Data->type('integer')->name('regionalConcilNumber')
->value(11778)
)
)
);
The code generates the following request:
POST http://saomc11024412/cgi-bin/siebel-soap.pl HTTP/1.1
Accept: text/xml
Accept: multipart/*
Accept: application/soap
Content-Length: 681
Content-Type: text/xml; charset=utf-8
SOAPAction: "urn:SiebelPhysician#FindByRCN"
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/enc
+oding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:namesp5="http://namespaces.soaplite.com/perl"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsdl="urn:SiebelPhysician"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<xsdl:FindByRCN>
<FindByRCNRequest si:type="namesp5:complex">
<federativeUnity xsi:type="xsd:string">PR</federativeU
+nity>
<regionalConcilNumber xsi:type="xsd:integer">11778</re
+gionalConcilNumber>
</FindByRCNRequest>
</xsdl:FindByRCN>
</soap:Body>
</soap:Envelope>
From the SOAP::Lite client side, I do need to invoke the method FindByRCN (instead of using FindByRCNRequest or the server just replies that the method does not exists).
It's quite confusing because I understand that the SOAPAction header should take care of everything regarding telling the server "hey, I want to invoke this method" and the XML of the request should not include the <xsdl:FindByRCN> element. Otherwise I'm not just sending a document but asking for a method and passing some parameters. This is just like RPC style.
I'm wondering if I'm not understand the patterns of SOAP message regarding document style of messages or if the SOAP::Lite interface is just a bit confusing.
Below is the complete WSDL content.
<?xml version="1.0"?>
<definitions name="SiebelPhysicians"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsdl="urn:SiebelPhysician"
targetNamespace="urn:SiebelPhysician"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<xsd:schema targetNamespace="urn:SiebelPhysician">
<xsd:complexType name="FindByRCNRequest">
<xsd:sequence>
<xsd:element name="federativeUnity" type="xsd:string"/>
<xsd:element name="regionalConcilNumber" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="FindByRCNResponse">
<xsd:sequence>
<xsd:element name="firstName" type="xsd:string"/>
<xsd:element name="lastName" type="xsd:string"/>
<xsd:element name="type" type="xsd:string"/>
<xsd:element name="status" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</types>
<message name="FindByRCNRequest">
<part name="FindByRCNRequestSoapMsg" element="xsdl:FindByRCNReques
+t"/>
</message>
<message name="FindByRCNResponse">
<part name="FindByRCNResponseSoapMsg" element="xsdl:FindByRCNRespo
+nse"/>
</message>
<portType name="SiebelPhysician_PortType">
<operation name="FindByRCN">
<input message="xsdl:FindByRCNRequest" />
<output message="xsdl:FindByRCNResponse" />
</operation>
</portType>
<binding name="SiebelPhysicianBinding" type="xsdl:SiebelPhysician_Po
+rtType">
<soap:binding style="document" transport="http://schemas.xmlsoap.o
+rg/soap/http"/>
<operation name="FindByRCN">
<soap:operation style="document" soapAction="urn:SiebelPhysician
+#FindByRCN"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="SiebelPhysician">
<documentation>SOAP service to query physicians in Siebel database
+</documentation>
<port name="SiebelPhysician_PortType" binding="xsdl:SiebelPhysicia
+nBinding">
<soap:address location="http://saomc11024412/cgi-bin/siebel-soap
+.pl"/>
</port>
</service>
</definitions>
When I import it other places (like soapUI) I get a request like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envel
+ope/" xmlns:urn="urn:SiebelPhysician">
<soapenv:Header/>
<soapenv:Body>
<urn:FindByRCNRequest/>
</soapenv:Body>
</soapenv:Envelope>
With such request, I got the following error from the server:
<soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/enc
+oding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s
+oapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://
+www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soa
+p/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>SOAPAction shall match 'uri#method' if present (
+got 'urn:SiebelPhysician#FindByRCN', expected 'urn:SiebelPhysician#Fi
+ndByRCNRequest'</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Not quite I was expecting.
Thanks,
Alceu Rodrigues de Freitas Junior
---------------------------------
"You have enemies? Good. That means you've stood up for something, sometime in your life." - Sir Winston Churchill