I have a SOAP webservice and in SOAP UI I see that there are methods with the same name. So, for example, there are 2 CreateNewContact methods, one of which takes 3 parameters and the other 4. Below are the stubs generated by SOAP UI
Method 1 Stub:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rfp="http://test.com/testWebservice/">
<soapenv:Header/>
<soapenv:Body>
<rfp:CreateNewContact_FullName>
<!--Optional:-->
<rfp:fullName>?</rfp:fullName>
<!--Optional:-->
<rfp:email>?</rfp:email>
<!--Optional:-->
<rfp:telNo>?</rfp:telNo>
</rfp:CreateNewContact_FullName>
</soapenv:Body>
</soapenv:Envelope>
Method 2 Stub:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rfp="http://test.com/testWebservice/">
<soapenv:Header/>
<soapenv:Body>
<rfp:CreateNewContact_FirstLastName>
<!--Optional:-->
<rfp:firstName>?</rfp:firstName>
<!--Optional:-->
<rfp:lastName>?</rfp:lastName>
<!--Optional:-->
<rfp:email>?</rfp:email>
<!--Optional:-->
<rfp:telNo>?</rfp:telNo>
</rfp:CreateNewContact_FirstLastName>
</soapenv:Body>
</soapenv:Envelope>
When I call the CreateNewContact method with 4 parameters using PHP SoapClient, it looks like I'm getting the response from the other method.
How can I specify which method to use using SoapClient?
Thanks,
As you can read here:
If you are using WSDL based SOAP requests and you have more than one
operation in your binding (with the same parameters), make sure the
style is set to rpc, NOT body! When you specify
'body' here, all that will be transmitted in the request is the
parameters for the function call, and SoapServer->handle() will use
the first function it finds with the same parameter-makeup to handle
the call. The actual method to call will only be included in the
request when your type is set to 'rpc', resulting in the expected
behavior
Therefore, you should check in your WSDL the operation element, which provides binding information from the abstract operation to the concrete SOAP operation.
For example:
<definitions ....>;
<binding .... >;
<operation .... >;
<soap12:operation soapAction="xs:anyURI" ?
soapActionRequired="xs:boolean" ?
style="rpc|document" ?
wsdl:required="xs:boolean" ? /> ?
</soap12:operation>
</binding>;
</definitions>
The style attribute value, if present, is a string that specifies the style for the operation. The style attribute indicates whether the operation is RPC-oriented (a messages containing parameters and return values) or document-oriented (a message containing documents). If the style attribute is omitted from the soap12:operation element, then the operation inherits the style specified or implied by the soap12:binding element in the containing wsdl:binding element.
So, in short, to solve your problem you should change the operation style from "document" to "rpc" in your WSDL.
As a further reference: https://bugs.php.net/bug.php?id=49169
I have faced the same with travelport universal API, I ended up modifying my local wsdl file to use different name for each method and it worked perfectly.
Related
Im trying to access a specific method from a webservice. i can access the webservice, i know because __getFunctions() is working. What i need to know is which arguments i have to pass, to call getItem(). In SoapUI a request looks like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:int="http://webservice.mks.com/2009/Integrity" xmlns:sch="http://webservice.mks.com/2009/Integrity/schema">
<soapenv:Header/>
<soapenv:Body>
<int:getItem>
<!--Optional:-->
<arg0 transactionId="?" sch:ItemId="8720303">
<sch:Username>--</sch:Username>
<sch:Password>--</sch:Password>
<sch:InputField>State</sch:InputField>
</arg0>
</int:getItem>
</soapenv:Body>
</soapenv:Envelope>
I think i have to pass a ItemId, Username, Password and InputField. But i have no Idea in which way i have to. I am using php and i called the method like this:
$result = $client->__soapCall('getItem',array('arg0'=>array('transactionId'=>'?','ItemId'=>'8720303','InputField'=>'State', 'Username'=>'--','Password'=>'--')));
How can I generate this schema using php soap client cant seem to get a way
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:loc="http://www.csapi.org/schema/parlayx/subscribe/manage/v1_0/local">
<soapenv:Header>
<tns:RequestSOAPHeader xmlns:tns="http://www.namesapace.com/common/v2_1">
<tns:one>***</tns:one>
<tns:two>***</tns:three>
<oauth_token>***</oauth_token>
</tns:RequestSOAPHeader>
</soapenv:Header>
<soapenv:Body>
<loc:ProductRequest>
<subInfo>
<productID>***</productID>
<isAutoExtend>0</isAutoExtend>
</subInfo>
</loc:ProductRequest>
</soapenv:Body>
</soapenv:Envelope>
On top of using the client, sometimes it may not bind to the namespace especially if using different soap versions or other strange reasons. Solved it by overriding the soap class and replacing the ns1 and ns2 values as described here http://php.net/manual/en/soapclient.dorequest.php#74123
IF no success with php soapclient, just post the request with curl.
Example in this answer - SOAP request in PHP with CURL
I'm having a problem in order to create a soap call. As one can see the header that is being supplied from a 3rd party client doesn't have a header name. I need to create a soap call by passing the username and password to the soap request which doesn't have a name in the header. I have tried several examples but no success. The call below works in soap UI but I'm having serious problems when it comes to php. Any help would be much appreciated
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:int="http://namespace.example.com/">
<soapenv:Header>
<int:password>123</int:password>
<int:login>abc</int:login>
</soapenv:Header>
<soapenv:Body>
<int:getEventTree>
<!--Optional:-->
<lang>en</lang>
</int:getEventTree>
</soapenv:Body>
</soapenv:Envelope>
Please take a look at http://php.net/manual/en/soapclient.dorequest.php
You can use code like:
$response = $soapClient->__doRequest(
$request,
$endpoint,
$soapAction,
$soapVersion,
$one_way
);
$request could be defined as a string containing xml, such as:
$request =
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/""xmlns:int="http://namespace.example.com/">
<soapenv:Header>
<int:password>123</int:password>
<int:login>abc</int:login>
</soapenv:Header>
<soapenv:Body>
<int:getEventTree>
<!--Optional:-->
<lang>en</lang>
</int:getEventTree>
</soapenv:Body>
</soapenv:Envelope>';
You can define the rest of the arguments in the __doRequest() call depending on your configuration.
I am working with Magento 1.6 and try to call the Soap API V2 to get product-information (attributes and additional attributes).
If use soapUI or try to generate a request in java to get information of the product and its additional attributes a new entry gets written to the system log, saying:
2012-01-20T08:33:04+00:00 DEBUG (7): array_merge() [<a href='function.array merge'>function.array-merge</a>]: Argument #2 is not an array/opt/website/magento/app/code/core/Mage/Catalog/Model/Product/Api/V2.php
So I neither get those attributes nor can I update these on a product.
Does anybody have idea to come over this issue!
thanks
Well I figured it out!
There seems to be a "bug" in that file! So if you request only one attribute the array_merge() function can't join the variable because the $attribute variable is not an array.
Try to send multiple attributes with soaoUI:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Magento">
<soapenv:Header/>
<soapenv:Body>
<urn:catalogProductInfoRequestParam>
<sessionId>b595ed396f1901142cb284e4c280df82</sessionId>
<productId>7271</productId>
<!--Optional:-->
<store>0</store>
<!--Optional:-->
<attributes>
<additional_attributes>
<complexObjectArray>atribute</complexObjectArray>
<complexObjectArray>atribute</complexObjectArray>
<complexObjectArray>atribute</complexObjectArray>
<complexObjectArray>atribute</complexObjectArray>
<complexObjectArray>atribute</complexObjectArray>
</additional_attributes>
</attributes>
<!--Optional:-->
<identifierType/>
</urn:catalogProductInfoRequestParam>
</soapenv:Body>
</soapenv:Envelope>
I am using Zend_Soap_Client to query data from a webservice provided by SAP. Since the auto-generated WSDL file has a few flaws, I use the non-WSDL mode of the client.
I managed to successfully call a webservice which only requires simple parameters, like strings. Example:
This is what SAP expects:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:sap-com:document:sap:soap:functions:mc-style">
<soapenv:Header/>
<soapenv:Body>
<urn:Ze12RfcGetCustHistoryNew>
<PiDateHigh>2011-12-31</PiDateHigh>
<PiDateLow>1970-01-01</PiDateLow>
<PiKunnr>1</PiKunnr>
</urn:Ze12RfcGetCustHistoryNew>
</soapenv:Body>
</soapenv:Envelope>
This is my (working) code in PHP (with $soapClient already initialized in non-WSDL mode):
$soapClient->Ze12RfcGetCustHistoryNew(
new SoapParam(date('Y-m-d'), 'PiDateHigh'),
new SoapParam('1970-01-01', 'PiDateLow'),
new SoapParam('1', 'PiKunnr')
);
But as soon as I have to pass more complex parameters to the service, it does not work. Again, an example:
This is what SAP expects:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:sap-com:document:sap:soap:functions:mc-style">
<soapenv:Header/>
<soapenv:Body>
<urn:Ze12RfcGetCustHistoryNew>
<PiDateHigh>2011-12-31</PiDateHigh>
<PiDateLow>1970-01-01</PiDateLow>
<PiKunnr>1</PiKunnr>
<PiTBelegart>
<item>
<BelegartTyp>FAKTURA</BelegartTyp>
<Belegart>ZF2</Belegart>
</item>
</PiTBelegart>
</urn:Ze12RfcGetCustHistoryNew>
</soapenv:Body>
</soapenv:Envelope>
I have tried to use a multi-dimensional array containing SoapParams, but that did not work. In WSDL mode, I could pass the params as an array, without the need of using SoapParams. How can I do this in non-WSDL mode?
just a "quick-hit" ... I'm working in a different environment, but initially had my soap-value troubles too.
One solution for a particular problem was to pass complex arrays this way:
$data = (object)$complexArray;
$result = $webserviceClient->getResult($data);
"Casting" to object results in a StdClass object ... which often works fine for webservices.
Good Luck!
I have not come up with a nice solution for this yet - currently I pass the parameters to the client object as raw xml. That works, but does not seem to be the best way to do this. This is my code now:
$params = '
<PiDateHigh>2011-12-31</PiDateHigh>
<PiDateLow>1970-01-01</PiDateLow>
<PiKunnr>1</PiKunnr>
<PiTBelegart>
<item>
<BelegartTyp>FAKTURA</BelegartTyp>
<Belegart>ZF2</Belegart>
</item>
</PiTBelegart>
';
$result = $this->_client->Ze12RfcGetCustHistoryNew(new SoapVar($params,XSD_ANYXML));