400 Bad Request : Consuming WCF basicHttpBinding (Soap) using JScript/VBScript - soap

var oXMLDoc, oXMLHttp, soapRequest, soapResponse;
oXMLHttp = new ActiveXObject("Microsoft.XMLHTTP");
oXMLHttp.open("POST", "http://nerdbox/HelloService.svc", false);
// Add HTTP headers
oXMLHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
oXMLHttp.setRequestHeader("SOAPAction", "http://tempuri.org/IHelloService/SayHello");
// Form the message
soapRequest = '<?xml version="1.0" encoding="utf-16"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><SayHello xmlns="http://tempuri.org/"><name>Zuhaib</name></SayHello></soap:Body></soap:Envelope>';
WScript.Echo("Request : " + soapRequest);
oXMLHttp.send(soapRequest);
soapResponse = oXMLHttp.responseXML.xml;
WScript.Echo("Respose : " + soapResponse);
Whats wrong with this JScript? why am I getting 400 Bad Request. I read similar threads in stackoverflow .. some say its soap message formatting problem.
This is what the message looks like if I take it from fiddler.

Try changing your action from IHelloService to HelloService.
And let me ask you, why are you doing it the hard way. Just add a webHttpBinding and use JSON.
See a very easy example here.

I had to change your code to the following to get it to run in VBSEdit...then I (obviously) got the error about it not being able to find the resource...but change your code to this and see if it makes a difference?
Dim oXMLDoc, oXMLHttp, soapRequest, soapResponse
Set oXMLHttp = CreateObject("Microsoft.XMLHTTP")
oXMLHttp.open "POST", "http://nerdbox/HelloService.svc", False
'// Add HTTP headers
oXMLHttp.setRequestHeader "Content-Type", "text/xml; charset=utf-8"
oXMLHttp.setRequestHeader "SOAPAction", "http://tempuri.org/IHelloService/SayHello"
'// Form the message
soapRequest = "<?xml version=""1.0"" encoding=""utf-16""?><soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""><soap:Body><SayHello xmlns=""http://tempuri.org/""><name>Zuhaib</name></SayHello></soap:Body></soap:Envelope>"
WScript.Echo "Request : " + soapRequest
oXMLHttp.send soapRequest
soapResponse = oXMLHttp.responseXML.xml
WScript.Echo "Respose : " + soapResponse

Related

Google Apps Script SOAP response is encoded. How/where to add base64decode to see the response as xml

Below is my working Google apps script SOAP API envelop call. It works to connect ok and as you can see below it returns a response, but my response is encoded. How/where to add a bit to do a Base64decode to see the XML that is returned instead of the string of characters? I am totally new to SOAP API and still a newbie to apps script too. Thanks!
function getData() {
var webservice = ‘https://someplace.com/services/stuff/’;
var xml = '<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://someurlhere.com">'
+ '<soapenv:Header/>'
+ '<soapenv:Body>'
+ '<ser:getReportXML soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> '
+ '<in0 xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">' + userid + '</in0> '
+ '<in1 xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">' + password + '</in1> '
+ '<in2 xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">' + startDate + '</in2> '
+ '<in3 xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">' + endDate + '</in3> '
+ '</ser:getReportXML> '
+ '</soapenv:Body>'
+' </soapenv:Envelope>'
var options = {
headers: {"SOAPAction" :"https://someplace.com/services/stuff/"},
method: "post",
contentType: "text/xml",
payload: xml,
muteHttpExceptions: true,
};
var serviceaddress = webservice;
var response = UrlFetchApp.fetch(serviceaddress, options);
Logger.log(response);
};
It returns an encoded string in the response, but I want to see the actual XML results:
[19-01-31 11:46:02:122 PST] <?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><ns1:getReportXMLResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1=" http://someurlhere.com "><getReportXMLReturn xsi:type="soapenc:base64Binary" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">WMui8xyxcPQXmZgSerdPd94bwWxGsAMgdmVyc2lvbj0iFRxlTSerdgiPz4NCg0KPQFET0NUW
I am trying to get the response output to look like xml and not a string of characters
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ETRANS PUBLIC "-//Something//ethings DTD//EN" "https://www.url.com/dtd/ethings_1_0.dtd">
<ETRANS>
<USER ID="AABB1122" USER_NAME="Smith, John" DATE="2019-02-01 09:41:45" DEPT_ID=""/>
</ETRANS>
So I figured out that my response does have the encoded body of the XML, but it also has all these extra bits in the response before the actual encoded data, so the decoder fails as it doesn't know what to do with this bit shown here at the beginning of the response
[19-01-31 11:46:02:122 PST] <?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><ns1:getReportXMLResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1=" http://someurlhere.com "><getReportXMLReturn xsi:type="soapenc:base64Binary" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
and a few more bits at the bottom that are like some closing of the above bits. Is there something I need to pass in my request to have the SOAP request only return the character string and not these extra bits that look like it is putting the "envelope" around the encoded data it is sending back?
I finally figured this out. I don't know if there is a "better" way to do this, but if you see what I did maybe you might share that "better" way. So I added the "NEW BIT" lines below. I had to get rid of the SOAP Envelop in order to decode the base64 bit. The only way I could figure out in Google Apps Script was to save the response as a file as that seemed to "magically" take the SOAP away. So then I had to get the base64 bit that was left that was in the MyTestFile file I created into a text string and decode/convert that and it created the xml I was looking for. I hope this can help someone else out.
function getData() {
var webservice = ‘https://someplace.com/services/stuff/’;
var newDocName = 'MyTestFile'
var xml = '<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://someurlhere.com">'
+ '<soapenv:Header/>'
+ '<soapenv:Body>'
+ '<ser:getReportXML soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> '
+ '<in0 xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">' + userid + '</in0> '
+ '<in1 xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">' + password + '</in1> '
+ '<in2 xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">' + startDate + '</in2> '
+ '<in3 xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">' + endDate + '</in3> '
+ '</ser:getReportXML> '
+ '</soapenv:Body>'
+' </soapenv:Envelope>'
var options = {
headers: {"SOAPAction" :""},
method: "post",
contentType: "text/xml",
payload: xml,
muteHttpExceptions: true,
};
var serviceaddress = webservice;
var response = UrlFetchApp.fetch(serviceaddress, options).getContentText();
//Logger.log(response);
//NEW BIT BEGINS HERE THAT DECODED THE RESPONSE
var blob = DriveApp.createFile('dummy',response, 'text/html').getBlob();
var resource = {
title: newDocName,
convert: true,
mimeType: 'application/vnd.google-apps.file'
};
var file = Drive.Files.insert(resource,blob);
var doc = DocumentApp.openById(file.id);
var text = doc.getBody().getText();
var decoded = Utilities.base64Decode(text,Utilities.Charset.UTF_8); // This was a byte array
var decodedstr = Utilities.newBlob(decoded).getDataAsString() // This was the xml I was looking for
Logger.log(decodedstr);
//NEW BIT ENDS HERE
};

Run-time error with http setRequestHeader

Public Function WebRequest(url As String, sVal1 As String, sVal2 As Integer) As String
Dim xmlhttp As MSXML2.xmlhttp
Set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP")
xmlhttp.setRequestHeader "Content-Type", "application/json"
'xmlhttp.setRequestHeader "Accept", "text/xml"
'xmlhttp.setRequestHeader "Value1", sVal1
'xmlhttp.setRequestHeader "Value2", sVal2
xmlhttp.open "GET", url, False
xmlhttp.send
WebRequest = xmlhttp.responseText
Set xmlhttp = Nothing
End Function
When I run this function, even with the other paramaters commented out, it fails at the line: xmlhttp.setRequestHeader "Content-Type", "application/json" no matter what I put into the request header fields.
I get the error: Run-time error '-2147467259(80004005)' Unspecified error if I comment out the setRequestHeader line then it works fine, but the API returns that I am missing header fields (expected) I have ried MS XML v3.0 and v6.0 and am completely out of ideas...
Set your request headers after opening the request.

Check VAT Number at VIES with classic ASP + SOAP

I'm trying to check European VAT Number at VIES via Webservice:
with my poor knowledge I built the following routine:
<%
strEnvelope="<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:urn=""urn:ec.europa.eu:taxud:vies:services:checkVat:types"">"
strEnvelope=strEnvelope&"<soapenv:Header/>"
strEnvelope=strEnvelope&"<soapenv:Body>"
strEnvelope=strEnvelope&"<urn:checkVat>"
strEnvelope=strEnvelope&"<urn:countryCode>DE</urn:countryCode>"
strEnvelope=strEnvelope&"<urn:vatNumber>247856515</urn:vatNumber>"
strEnvelope=strEnvelope&"</urn:checkVat>"
strEnvelope=strEnvelope&"</soapenv:Body>"
strEnvelope=strEnvelope&"</soapenv:Envelope>"
set objHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP.6.0")
objHTTP.open "post", "http://ec.europa.eu/taxation_customs/vies/services/checkVatService"
objHTTP.setRequestHeader "Content-Type", "text/xml"
objHTTP.setRequestHeader "SOAPMethodName", "checkVat"
objHTTP.send strEnvelope
strReturn = objHTTP.responseBody
response.write strReturn
%>
but I got this answer
猼慯㩰湅敶潬数ç æ±­ç®çŒºæ…¯ãµ°æ ¢ç‘´ã©°â¼¯æ³æ•¨æ…­â¹³æµ¸ç¬æ…¯â¹°ç‰¯â½§æ½³ç¡æ”¯ç™®æ±¥ç¯â½¥ã¸¢çŒ¼æ…¯ã©°æ½‚祤㰾档æ¥å™«ç‘¡æ•’ç³æ¹¯æ•³ç æ±­ç®âˆ½ç‰µã©®æ¥æ”®ç‰µç¯â¹¡ç•¥çºç¡¡æ‘µç˜ºæ•©ã©³æ•³ç™²æ©ç¥æŒºæ•¨æ­£æ…–㩴祴数≳㰾潣湵牴ä¹æ‘¯ã¹¥ä•„⼼潣湵牴ä¹æ‘¯ã¹¥ç˜¼ç‘¡ç•Žæ‰­ç‰¥ãˆ¾ãœ´ã”¸ã”¶ã”±â¼¼æ…¶ä¹´æµµæ•¢ã¹²çˆ¼ç…¥æ•µç‘³æ…„整㈾㄰ⴷ㜰ㄭ⬵㈰〺㰰爯煥敵瑳慄整㰾慶楬㹤牴敵⼼慶楬㹤渼浡㹥ⴭ㰭港浡㹥愼摤敲ç³â´¾â´­â¼¼æ‘¡ç‰¤ç¥ã¹³â¼¼æ¡£æ¥å™«ç‘¡æ•’ç³æ¹¯æ•³ã°¾çŒ¯æ…¯ã©°æ½‚祤㰾猯慯㩰湅敶潬数> 猼慯㩰湅敶潬数ç æ±­çÂ®çŒºæ…¯ãµ°æ ¢ç‘´ã©°â¼¯æ³敨慭⹳浸ç¬慯⹰牯⽧潳ç¡æâ€Â¯Ã§â„¢Â®Ã¦Â±Â¥Ã§Â¯â½¥ã¸¢çŒ¼æ…¯ã©°æ½‚祤㰾档æ¥噫瑡敒ç³湯敳ç æ±­ç®∽牵㩮æÂ¥æâ€Â®Ã§â€°ÂµÃ§Â¯â¹¡ç•¥çº硡摵瘺敩㩳敳癲æ©ç¥挺敨正慖㩴祴数≳㰾潣湵牴ä¹摯㹥䕄⼼潣湵牴ä¹摯㹥瘼瑡畎扭牥㈾㜴ãâ€Â¸Ã£â€Â¶Ã£â€Â±Ã¢Â¼Â¼Ã¦â€¦Â¶Ã¤Â¹Â´Ã¦ÂµÂµÃ¦â€¢Â¢Ã£Â¹Â²Ã§Ë†Â¼Ã§â€¦Â¥Ã¦â€¢ÂµÃ§â€˜Â³Ã¦â€¦â€žÃ¦â€¢Â´Ã£Ë†Â¾Ã£â€žÂ°Ã¢Â´Â·Ã£Å“°ã„­â¬µãˆ°ã€ºã°°çˆ¯ç…¥æ•µç‘³æ…„整㰾慶楬㹤牴敵⼼慶楬㹤渼浡㹥ⴭ㰭港浡㹥愼摤敲ç³ⴾⴭ⼼摡牤ç¥㹳⼼档æ¥噫瑡敒ç³湯敳㰾猯慯㩰潂祤㰾猯慯㩰湅敶潬数>
can give some hints?
Thanks
The text representation of the response is in the responseText property, so:
strReturn = objHTTP.responseText

google apps script soap client without wsdl

I am attempting to access the Numara Footprints web services API from google apps script. There is no wsdl for the web service, but the methods are well documented. All of the examples of using Google Apps Script Soap Service assume the existence of a wsdl file, which makes it a non-starter for my purposes. So I am trying to use UrlFetchApp instead. By using the sample php code that Numara Footprints provides, I established what the request should look like, and wrote the following code in google apps script:
function sendHttpPost() {
var payload= '<?xml version="1.0" encoding="utf-8"?>' +
'<SOAP-ENV:Envelope'+
'xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"'+
'xmlns:ns1="MRWebServices"'+
'xmlns:xsd="http://www.w3.org/2001/XMLSchema"' +
'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
'xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"' +
'SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'+
'<SOAP-ENV:Body>'+
'<ns1:MRWebServices__search>'+
'<param0 xsi:type="xsd:string">ACCOUNT NAME</param0>'+
'<param1 xsi:type="xsd:string">PASSWORD</param1>'+
'<param2 xsi:type="xsd:string"></param2>'+
'<param3 xsi:type="xsd:string">'+
"SELECT * from MASTER1 where mrid='16888'</param3>"+
'</ns1:MRWebServices__search>'+
'</SOAP-ENV:Body>'+
'</SOAP-ENV:Envelope>';
var headers =
{
"SOAPAction" :encodeURIComponent("MRWebServices#MRWebServices__search")
};
var options =
{
"contentType": "text/xml; charset=utf-8",
"method" : "post",
"headers" : headers,
"payload" : payload
};
UrlFetchApp.fetch("http://FOOTPRINTS SERVER/MRcgi/MRWebServices.pl", options);
}
This code contacts the server successfully and gets the following error message returned:
Request failed for http://FOOTPRINTS SERVER/MRcgi/MRWebServices.pl
returned code 500. Server response:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>Application failed during request deserialization:
not well-formed (invalid token) at line 1, column 70, byte 70 at
C:/FootPrints/bin/Perl/lib/XML/Parser.pm line 187 </faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope> (line 40)
I don't know of any way to get more detailed error messages, and I don't know what the problem is. The xml that I am sending is copied directly from the PHP code that works perfectly.
I'm wondering if anyone either:
can see a problem with the google apps script code above or
can tell me how to use the Google Apps Script soap service when I don't have a wsdl file or
knows of a way to get a web service to return more error details.
Thanks in advance. I've looked everywhere that I can think of but not found an answer.
The payload var in the above code needed spaces between the XML elements. Corrected code (note spaces at the end of each line):
var payload= '<?xml version="1.0" encoding="utf-8"?> ' +
'<SOAP-ENV:Envelope '+
'xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" '+
'xmlns:ns1="MRWebServices" '+
'xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' +
'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
'xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" ' +
'SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> '+
'<SOAP-ENV:Body> '+
'<ns1:MRWebServices__search> '+
'<param0 xsi:type="xsd:string">ACCOUNT NAME</param0> '+
'<param1 xsi:type="xsd:string">PASSWORD</param1> '+
'<param2 xsi:type="xsd:string"></param2> '+
'<param3 xsi:type="xsd:string"> '+
"SELECT * from MASTER22 where mrid='16888'</param3> "+
'</ns1:MRWebServices__search> '+
'</SOAP-ENV:Body> '+
'</SOAP-ENV:Envelope>';
Also, in the headers, I did not need to use encodeURIComponent(). Corrected code:
var headers =
{
"SOAPAction" :"MRWebServices#MRWebServices__search"
};

Sending a 'application/soap+xml' SOAP request using Classic ASP

Any help with this would be appreciated; I've been at it for a few days now.
Below is the code that I've got so far; unfortunatly when I run it I get a HTTP 415 error; Cannot process the message because the content type 'text/xml; charset=UTF-8' was not the expected type 'application/soap+xml; charset=utf-8'.
I have to send the content-type of application/soap+xml as this is the only type that the web service allows; and I have to do it in classic ASP.
I've tried changing the 'send' line to "objRequest.send objXMLDoc.XML" but this then gives me a HTTP 400 Bad Request error.
strXmlToSend = "<some valid xml>"
webserviceurl = "http://webservice.com"
webserviceSOAPActionNameSpace = "avalidnamespace"
Set objRequest = Server.createobject("MSXML2.XMLHTTP.3.0")
objRequest.open "POST", webserviceurl, False
objRequest.setRequestHeader "Content-Type", "application/soap+xml"
objRequest.setRequestHeader "CharSet", "utf-8"
objRequest.setRequestHeader "action", webserviceSOAPActionNameSpace & "GetEstimate"
objRequest.setRequestHeader "SOAPAction", webserviceSOAPActionNameSpace & "GetEstimate"
Set objXMLDoc = Server.createobject("MSXML2.DOMDocument.3.0")
objXMLDoc.loadXml strXmlToSend
objRequest.send objXMLDoc
set objXMLDoc = nothing
Here's what I've used successfully in the past:
Set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")
xmlhttp.open "POST", url, false
xmlhttp.setRequestHeader "Content-Type", "text/xml; charset=utf-8"
xmlhttp.setRequestHeader "SOAPAction", "http://www.mydomain.com/myaction"
xmlhttp.send postdata
xml = xmlhttp.responseText
When you pass an XML DOM ot the send method the Content-Type is always set to "text/xml".
If you want to control the content type then you must pass a string. Don't bother loading the XML string into a DOM only to call the xml property since that may change the content of the xml declaration. BTW what does the xml declaration look like in the XML string and are you certain that the xml is correct? The encoding on the xml declare if present should say "UTF-8".
Don't send a header CharSet it means nothing, CharSet is an attribute of the Content-Type header.
Don't use XMLHTTP from inside ASP its not safe.
Hence your code ought to look like this:-
strXmlToSend = "<some valid xml>"
webserviceurl = "http://webservice.com"
webserviceSOAPActionNameSpace = "avalidnamespace"
Set objRequest = Server.Createobject("MSXML2.ServerXMLHTTP.3.0")
objRequest.open "POST", webserviceurl, False
objRequest.setRequestHeader "Content-Type", "application/soap+xml; charset=UTF-8"
objRequest.setRequestHeader "action", webserviceSOAPActionNameSpace & "GetEstimate"
objRequest.setRequestHeader "SOAPAction", webserviceSOAPActionNameSpace & "GetEstimate"
objRequest.send strXmlToSend
Not sure about that "action" header either looks superflous to me. Perhaps this will still fail in some way but it shouldn't complain about the Content-Type header anymore.