I have a problem with the allposters.com SOAP (http://webservice.allposters.com/). I am trying to fetch some product information via (a slightly modified) nuSOAP PHP library (http://sourceforge.net/projects/nusoap/) on a PHP 5.3 installation.
My request is (all the characters are exactly like here, they are not converted to entities):
POST /ProductInformationService.asmx HTTP/1.0
Host: webservice.allposters.com
User-Agent: NuSOAP/0.9.5 (1.123)
Content-Type: text/xml; charset=UTF-8
SOAPAction: "http://Webservice.Allposters.com/APCF.AffiliateWebService/ProductInformationService/GetProductByProductNumberInformation"
Content-Length: 570
<?xml version="1.0" encoding="UTF-8" ?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetProductByProductNumberInformation xmlns="http://Webservice.Allposters.com/APCF.AffiliateWebService/ProductInformationService">
<APCSearchXml>
<WebSiteID>1234567890</WebSiteID>
<SearchTerm>1234567</SearchTerm>
<LanguageID>1</LanguageID>
<CurrencyCode>USD</CurrencyCode>
</APCSearchXml>
</GetProductByProductNumberInformation>
</soap:Body>
</soap:Envelope>
And I get the error
Length cannot be less than zero. Parameter name: length
in this specific response
HTTP/1.1 200 OK
Connection: keep-alive
Date: Tue, 08 Jan 2013 18:46:59 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 821
<APC_Search_Results>
<StatusCode>1</StatusCode>
<Search_Error>
<ErrorNumber>1</ErrorNumber>
<ErrorDescription>Length cannot be less than zero. Parameter name: length</ErrorDescription>
</Search_Error>
</APC_Search_Results>
The communication seems to be working fine; if I remove the "WebSiteID" element from my previous request, I would get
Index was out of range. Must be non-negative and less than the size of the collection.
Unfortunatelly, from the few examples I found on the web and from a 7-pages document on their website with a sample in Visual Basic (this is the only documentation I was able to find), I really can't figure out what I am missing, and that .NET error doesn't tell me something I can use.
Did someone experienced similar problems with the allposters.com affiliate webservice and have some advice?
You are using the Soap service in the wrong way.
If you look at the example on the page for the call "GetProductByProductNumberInformation" on http://webservice.allposters.com/ProductInformationService.asmx?op=GetProductByProductNumberInformation there is only a placeholder "string" mentioned, but you are sending a complete set of XML. This is probably wrong.
I don't know why you think you can send more than a string like the XML you did, but I found out that this service actually expects you to send your XML wrapped inside a CDATA so that it is just a string - the server then unpacks the string and does another XML parsing.
This implementation method is completely bullshit, because it circumvents the point of having a Soap Service with a WSDL description of what kind of parameters the service allows and expects - but you are most unlikely to change that.
So you have to make NuSoap to wrap your XML string inside CDATA tags, otherwise it won't work at all, I think.
The OP offered the following solution in a question edit, so I am moving to an answer proper:
<?xml version="1.0" encoding="UTF-8" ?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetProductByProductNumberInformation xmlns="http://Webservice.Allposters.com/APCF.AffiliateWebService/ProductInformationService">
<APCSearchXml>
<![CDATA[
<APC_Search_Query>
<WebSiteID>1234567890</WebSiteID>
<SearchText>123456</SearchText>
<LanguageID>1</LanguageID>
<CurrencyCode>USD</CurrencyCode>
</APC_Search_Query>
]]>
</APCSearchXml>
</GetProductByProductNumberInformation>
</soap:Body>
</soap:Envelope>
Related
How do you get the URI for using the SOAPClient which doesn't have the WSDL. The user has not provided us with the WSDL, but wanted to use their webservice using SOAP to get some information. I am looking for how to do it on PHP.
The confusion part is how to identify the URI value (target namespace). Based on their documentation,below is the sample they provided for SOAP call to me made.
The following is a sample SOAP 1.2 request and response. The placeholders shown need to be replaced with actual values.
**POST /webservices/wssamples/service.asmx HTTP/1.1
Host: www.samplecomponents.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length**
```
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<QueryAvailability xmlns="http://www.samplecomponents.com/webservices/">
<program_id>string</program_id>
<security_id>string</security_id>
<part_number>string</part_number>
</QueryAvailability>
</soap12:Body>
</soap12:Envelope>
```
**RESPONSE**
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<QueryAvailabilityResponse xmlns="http://www.samplecomponents.com/webservices/">
<QueryAvailabilityResult xmlns="http://www.samplecomponents.com/schemas/sample_availability.xsd">
<timestamp>dateTime</timestamp>
<item_count>unsignedInt</item_count>
<items>
<item>
<part_id>unsignedInt</part_id>
<manufacturer_part_number>string</manufacturer_part_number>
<stock_source>string</stock_source>
<digikey_part_number>string</digikey_part_number>
<description>string</description>
<quantity_available>unsignedInt</quantity_available>
<break_quantity>unsignedInt</break_quantity>
<rohs_compliant>bytes</rohs_compliant>
<flag_non_stock>boolean</flag_non_stock>
<flag_obsolete>boolean</flag_obsolete>
<flag_static_sensitive>boolean</flag_static_sensitive>
</item>
<item>
<part_id>unsignedInt</part_id>
<manufacturer_part_number>string</manufacturer_part_number>
<stock_source>string</stock_source>
<digikey_part_number>string</digikey_part_number>
<description>string</description>
<quantity_available>unsignedInt</quantity_available>
<break_quantity>unsignedInt</break_quantity>
<rohs_compliant>bytes</rohs_compliant>
<flag_non_stock>boolean</flag_non_stock>
<flag_obsolete>boolean</flag_obsolete>
<flag_static_sensitive>boolean</flag_static_sensitive>
</item>
</items>
</QueryAvailabilityResult>
</QueryAvailabilityResponse>
</soap12:Body>
</soap12:Envelope>
**HTTP POST**
The following is a sample HTTP POST request and response. The placeholders shown need to be replaced with actual values.
POST /webservices/wssamples/service.asmx/QueryAvailability HTTP/1.1
Host: www.samplecomponents.com
Content-Type: application/x-www-form-urlencoded
Content-Length: length
program_id=string&security_id=string&part_number=string```
**RESPONSE**
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<sample_availability xmlns="http://www.samplecomponents.com/schemas/sample_availability.xsd">
<timestamp>dateTime</timestamp>
<item_count>unsignedInt</item_count>
<items>
<item>
<part_id>unsignedInt</part_id>
<manufacturer_part_number>string</manufacturer_part_number>
<stock_source>string</stock_source>
<digikey_part_number>string</digikey_part_number>
<description>string</description>
<quantity_available>unsignedInt</quantity_available>
<break_quantity>unsignedInt</break_quantity>
<rohs_compliant>bytes</rohs_compliant>
<flag_non_stock>boolean</flag_non_stock>
<flag_obsolete>boolean</flag_obsolete>
<flag_static_sensitive>boolean</flag_static_sensitive>
</item>
<item>
<part_id>unsignedInt</part_id>
<manufacturer_part_number>string</manufacturer_part_number>
<stock_source>string</stock_source>
<digikey_part_number>string</digikey_part_number>
<description>string</description>
<quantity_available>unsignedInt</quantity_available>
<break_quantity>unsignedInt</break_quantity>
<rohs_compliant>bytes</rohs_compliant>
<flag_non_stock>boolean</flag_non_stock>
<flag_obsolete>boolean</flag_obsolete>
<flag_static_sensitive>boolean</flag_static_sensitive>
</item>
</items>
</sample_availability>
These is no reference to URI or target namespace to be supplied on this documentation. Any help much appreciated.
The "target namespace" is simply the XML namespaces of the element inside the SOAP body - in this case the QueryAvailability and QueryAvailabilityResponse elements which would be the root of the document if all the SOAP wrapping wasn't there.
So you just need to read the xmlns attributes in the sample, which show those elements to be in the namespace http://www.samplecomponents.com/webservices/
I have a PHP webapp that needs to connect to dynamics 365 ax soap services.
I was given a wsdl url and from there i am trying to get the values.
I used to get Forbidden error:608 now i get HTTP code 400 Bad Request
I am authenticating, getting token, and passing it with my POST method
POST /soap/services/ webservice?wsdl HTTP/1.1
Host: domain.sandbox.ax.dynamics.com
Accept: text/xml
Connection:Keep-Alive
Content-type: text/xml
Authorization: Bearer tokenString
Soapaction: "http://tempuri.org/webservice/method"
Content-Length lengthOfXML
Server Response:
HTTP/1.1 400 Bad Request Cache-Control: private Server:.. Strict-Transport-Security: max-age..; includeSubDomains Set-Cookie:ASP.NET_sessionId=.....;path=/;secure; HttpOnly Set-Cookie: ms-dyn-csrftoken:........ p3p: CP="No P3P policy defined. Read Microsoft privacy ... LinkID=271135" ..
//my XML that i pass as a curl POSTFIELD
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:i0="http://tempuri.org" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" >
<soap:Header>
<CallContext xmlns="schemas.microsoft.com/.../datacontracts">
<Company>some</Company>
<Language>en-us</Language>
<MessageId>0</MessageId>
<PartitionKey>286942</PartitionKey>
</CallContext>
</soap:Header>
<soap:Body>
<i0:nameofmethod >
<parameter>25536</parameter>
</i0:nameofmethod>
</soap:Body>
</soap:Envelope>
I need to get some kind of value a HTTP 200 OK at least.. I should get an array of strings.
I discovered that my Bad request was coming from adding a string in the header before my XML.
In some answers from other forums I was searching they suggested to add "xmlRequest=" string before the XML string itself and I forgot I added that and that was causing a problem.
I also removed the first line string with the UTF code
<?xml version="1.0" encoding="utf-8" ?>
And added the soap envelope directly.
I used SOAPUI to help make sure the structure is correct.
I am still facing a problem with calling my method though but that actually has a different error
Forbidden 1317 System.ComponentModel.Win32Exception The specified account does not exist
Which I am hoping I can find a fix. with a different POST.
For example I have found this free web service:
http://www.webservicex.net/ConvertTemperature.asmx
and I want to test my client, but I don't know what input parameters I should specify for my request.
This happens with a number of APIs that I want to test with. Is there any way to find out what possible values could be, since there is no documentation?
You've got several options here.
If you've installed Visual Studio you can use WCF Test Client to test the API.
More information on WCF Test Client HERE
Alternatively you can use SoapUI by SmartBear.
Most of the time you just specify the URL of the service and it will give you a list of all the available methods and what inputs they expect.
Actually, by the link you've submitted, there is a document with the parameters explained: http://www.webservicex.net/ConvertTemperature.asmx?op=ConvertTemp
Request:
POST /ConvertTemperature.asmx HTTP/1.1
Host: www.webservicex.net
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://www.webserviceX.NET/ConvertTemp"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ConvertTemp xmlns="http://www.webserviceX.NET/">
<Temperature>double</Temperature>
<FromUnit>degreeCelsius or degreeFahrenheit or degreeRankine or degreeReaumur or kelvin</FromUnit>
<ToUnit>degreeCelsius or degreeFahrenheit or degreeRankine or degreeReaumur or kelvin</ToUnit>
</ConvertTemp>
</soap:Body>
</soap:Envelope>
Temperature, FromUnit and ToUnit are the request/input parameters.
Considering the server is asmx-based, this URL should give you the full schema: http://www.webservicex.net/ConvertTemperature.asmx?wsdl
Hope I understood your question correctly.
P.S. It's not usually a good idea to test your code (e.g. auto-test) against a live (or production) system.
I'm a complete noob in XML and SOAP,
Could you give some advice on at least where to start, or some example?
(I'm not begging to write code for me)
Here are the specs:
I just expect to receive two double values. What is an easiest way to do it?
POST /CurrencyConvertor.asmx HTTP/1.1
Host: www.webservicex.net
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<ConversionRate xmlns="http://www.webserviceX.NET/">
<FromCurrency>PHP</FromCurrency>
<ToCurrency>USD or EUR</ToCurrency>
</ConversionRate>
</soap12:Body>
</soap12:Envelope>
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<ConversionRateResponse xmlns="http://www.webserviceX.NET/">
<ConversionRateResult>double</ConversionRateResult>
</ConversionRateResponse>
</soap12:Body>
</soap12:Envelope>
The above specs's origin: http://www.webservicex.net/CurrencyConvertor.asmx?op=ConversionRate
The first block is supposed to be a request, and the other response...
EDIT
Alright, I stopped at a standard PHP class, but I don't quite understand what is being asked for in this __doRequest method:
$client = new SoapClient();
$client->__doRequest ( <<<EOD
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<ConversionRate xmlns="http://www.webserviceX.NET/">
<FromCurrency>PHP</FromCurrency>
<ToCurrency>USD or EUR</ToCurrency>
</ConversionRate>
</soap12:Body>
</soap12:Envelope>
EOD
, "http://www.webservicex.net/CurrencyConvertor.asmx" , $???, $??? );
http://www.php.net/manual/en/soapclient.dorequest.php
What is action, and what should I put as version, I know - a soap version 1.2 but the parameter is int so it cannot be assigned a 1.2 value lol...
EDIT2:
Alright, this is what I've got so far, but it gets me an empty string...
$client = new SoapClient(null, array('location'=>'http://www.webservicex.net/CurrencyConvertor.asmx','uri'=>''));
$client->__doRequest ( <<<EOD
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<ConversionRate xmlns="http://www.webserviceX.NET/">
<FromCurrency>PHP</FromCurrency>
<ToCurrency>USD or EUR</ToCurrency>
</ConversionRate>
</soap12:Body>
</soap12:Envelope>
EOD
, "http://www.webservicex.net/CurrencyConvertor.asmx" , "ConversionRate", 2 );
echo "Response :<br>", htmlentities($client->__getLastResponse());
...I just dont get this 'uri' thing - beyond my understanding. It makes me want to hit my head to the wall.
Basically what you need are two parts.
A SOAPClient class, which solves the communication, knows about the server URL, sends requests and receives responses (which you got in XML in your question) and also triggers #2, which is:
The second part is an XML parser / marshaller, which can convert a request objects (containing fromCurrency and toCurrency) to a correct XML string the server can understand (according to the WSDL) and convert some XML into a response object again using the WSDL. This part is a bit tricky, but I found a lot of documentation for that, search for "SOAP PHP" and you get some examples). These two processes are called marshalling and unmarshalling (to help you find something quicker with Google). Your StockQuote webservice doesn't really provide a WSDL, which is basically a description of all possible operations (in your case just one: GetQuote) and its available objects (in your case only simple types string, which don't have to be defined, since they are WSDL standard)
I haven't done SOAP with PHP, but spent a lot of time with Java+SOAP and can understand how difficult it is. In theory you just send some XML to the server and get some XML back. But the XML sent has to be in the correct format and when you receive a response, you want to convert the response into an object and not deal with some XML string.
For a simple web service like this, you might consider constructing the XML request by hand (simply putting together the XML string) and substr the response to find the requested answer.
There is a webservice (WSDL) with a lot of functions. I want to call one of these functions with PHP.
The webservice provides a documentation wherein they put a format including header and xml, but I have no idea how I need to send the request from PHP. I searched for a couple of hours now, and I simply don't know.
An example request they provided:
POST POSTURL HTTP/1.1
Host: HOST
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "SOAPLOCATION"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Version xmlns="URL" />
</soap:Body>
</soap:Envelope>
The response I should receive is also given, but I can't even send the request.
How do I send a request with PHP to get the response?
I tried some PHP SoapClient things, but I can't find a easy to read tutorial or some clear explanation...
If anyone can help me, that would be great!
Mapping some typical information may look something like this.
$data = array(
'UserName' => $user->getUsername(),
'Password' => $user->getPassword(),
'Email' => $user->getEmail(),
'FirstName' => $user->getFirstName(),
'LastName' => $user->getLastName(),
);
$response = $this->getDatasource()->TheServiceMethodForCreatingAUser(
array(
'user' => $data
)
);
The response is then handled however you wish (via an entity or response object of some description). The header must be done seperately by using new SoapHeader().
Hope this helps.
I've an addition to the question:
The request is as following:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns="...">
<s:Body>
<Search>
<login>
<Wholesaler>...</Wholesaler>
<Username>...</Username>
<Password>...</Password>
</login>
<itemRequests>
<ItemRequest>
<ArticleId>int</ArticleId>
<SupplierId>int</SupplierId>
<QuantityRequested>int</QuantityRequested>
</ItemRequest>
</itemRequests>
</Search>
</s:Body>
</s:Envelope>
There are two SoapHeaders I need to send:
Content-Type: text/xml; charset=utf-8
SOAPAction: URI
I do know the service provider and the action identifier.
If I have the following variables
$service
$action
$request
$header
How can I send the request in PHP?
I tried
$client = new SoapClient($service);
$result = $client->__doRequest($request, $service, $action);
But I do not receive a response it seems...
This is what the response should like:
Date: Thu, 09 Aug 2012 08:01:40 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
Content-Length: 408
Cache-Control: private
Content-Type: text/xml; charset=utf-8
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SearchResponse xmlns="...">
<SearchResult>
<Wholesaler>...</Wholesaler>
<Username>...</Username>
<Error>false</Error>
<DateTime>2012-08-09T10:01:40.39125+02:00</DateTime>
<ItemResults />
</SearchResult>
</SearchResponse>
</s:Body>
</s:Envelope>
When I do a simple echo $result, the screen stays white and in the code there is no XML visible.