Error when calling dynamics ax soap service method from php - php

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.

Related

Is there any way to know what is the right form for the values of parameters in a SOAP API?

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.

How to get http request headers used by SoapClient?

I want to check my http headers that are sent via a SoapClient.
Yet it only offers quick functions to fetch the Soap headers:
/**
* Returns the SOAP headers from the last request
* #link http://php.net/manual/en/soapclient.getlastrequestheaders.php
* #return string The last SOAP request headers.
* #since 5.0.1
*/
public function __getLastRequestHeaders () {}
I am not interested in those.
How can I find out what http headers have been used for the request on the HTTP level?
Xdebug loses context at the _call and the client doesn't seem able to to fetch that information by itself.
How to proceed?
I ended up using Wireshark. I configured my SoapClient to just post against my local IP, for me that was 10.49.57.28.
I captured the any interface.
First I had to enable the protocols via: Ctrl + Shift + E. I selected "Enable All".
I used the filter:
http.request.method == "POST" and ip.addr == 10.49.57.28
I right clicked the relevant request and used:
Follow > TCP Stream
And there I had all the relevant request information:
POST / HTTP/1.1
Host: 10.49.57.28
Accept: */*
Accept-Encoding: deflate, gzip
SOAPAction: ""
Content-Type: text/xml; charset=utf-8
Content-Length: 2085
Expect: 100-continue
HTTP/1.1 100 Continue
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope ...
Of course, the response will be an error, yet I wasn't interested in that.

How to remove HTTP header from SOAP response

I am currently integrating with Kashflow and using SOAP calls to send Customer data to my Kashflow account from my Symfony2 site, and it should return the ID of the new customer - I need this in order to save it in the database at my end.
However, upon return, I get the HTTP header and not just the ID, which means it is not inserting it into the database as it needs to be an integer.
Here is the SOAP 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>
<InsertCustomerResponse xmlns="KashFlow">
<InsertCustomerResult>int</InsertCustomerResult>
<Status>string</Status>
<StatusDetail>string</StatusDetail>
</InsertCustomerResponse>
</soap12:Body>
</soap12:Envelope>
I am trying to retrieve the new ID by using:
return new Response((int)$response->soapBody->InsertCustomerResponse->InsertCustomerResult);
But even though the ID does get returned, it spits out the HTTP header above it. Is there any way of removing this? I have tried using preg_replace like this (where $return is the response from the SOAP call):
preg_replace('/((.*)\n)*(\d+)$/','$1',$return);
But it just returns a blank.
Any ideas?
Thanks in advance
I realised that I have to use getContent() on the return in order to get the data I needed.
So:
$response = $response->soapBody->InsertCustomerResponse->InsertCustomerResult;
return $response->getContent();
Which then only gets the data I need, and not the header as well.

AllPosters.com SOAP problematic response

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>

SOAP request with PHP

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.

Categories