Hi everyone,
I'm consuming a SOAP WebService (run UploadFile in hStreamService(input cContent, output ErrorCode , output ErrorDescription , output FileId))
and the WS sent me back a response like this:
--uuid:003d688f-f4ef-49cc-92dc-1b5067485459+id=9
Content-ID: <http://tempuri.org/0>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
<s:Envelope xmlns:s="schemas.xmlsoap.org/.../">
<s:Body>
<UploadResponse xmlns="services.kinetic.ch/">
<ErrorCode>0</ErrorCode>
<ErrorDescription/>
<FileId>c59f41b3-9786-48d8-ae5a-ccacbabce96a</FileId>
</UploadResponse>
</s:Body>
</s:Envelope>
36
--uuid:003d688f-f4ef-49cc-92dc-1b5067485459+id=9--
0
Has you can see, the response is between "--uuid"-marks enveloped and I receiving this error when I'm consuming the WS:
"Error receiving Web Service Response: Input stream is empty. Cannot create XMLParser. (11773)".
The WebService has done his job, but of course, due to the 11773 error, the output variables are empty.
Did exist however a way to get the soap-response in a XML-structure to extract after the method-values ?
Best Regards
Sam
Hi Peter,
My OE Version is 11.6.2... What I don't understand, is that SoapUI (for example) can correctly read the response ....
Hi there,
here an example for consuming a Multipart SOAP Webservice (QUERY and RESPONSE):
block-level on error undo, throw.
using OpenEdge.Core.*.
using OpenEdge.Net.HTTP.*.
using OpenEdge.Net.HTTP.IHttpRequest.
using OpenEdge.Net.HTTP.IHttpResponse.
using OpenEdge.Net.HTTP.IHttpResponse.
using OpenEdge.Net.HTTP.Lib.ClientLibraryBuilder.
using OpenEdge.Net.MessagePart.
using OpenEdge.Net.MultipartEntity.
define input parameter cFilePath as character no-undo.
define input parameter cFileName as character no-undo.
define output parameter FileId as character no-undo.
define variable oRequest as IHttpRequest no-undo.
define variable oResponse as IHttpResponse no-undo.
define variable oRequestBody as longchar no-undo.
define variable oResponseMemptrEntity as OpenEdge.Core.Memptr no-undo.
define variable oResponseMultipartEntity as OpenEdge.Net.MultipartEntity no-undo.
define variable oMessagePart as OpenEdge.Net.MessagePart no-undo.
define variable oByteBucket as OpenEdge.Core.ByteBucket no-undo.
define variable oBody as OpenEdge.Core.ByteBucket no-undo.
define variable oFile as OpenEdge.Core.ByteBucket no-undo.
define variable oPart as OpenEdge.Net.MessagePart no-undo.
define variable oFilePart as OpenEdge.Net.MessagePart no-undo.
define variable oHeader as OpenEdge.Net.HTTP.HttpHeaderBuilder no-undo.
define variable oEntity as OpenEdge.Net.MultipartEntity no-undo.
define variable mData as memptr no-undo.
define variable CRLF as character initial "~r~n" no-undo.
define variable cResponse as longchar no-undo.
define variable ErrorCode as character no-undo.
define variable ErrorDescription as character no-undo.
define variable cLength as integer no-undo.
define variable hXDoc as handle no-undo.
define variable lcUTF-8 as longchar no-undo.
define variable cSoapHeader as longchar no-undo.
define temp-table ttBody no-undo xml-node-name "Body"
field dummyField as character xml-node-name "dummyField".
define temp-table ttUploadResponse no-undo xml-node-name "UploadResponse"
field ErrorCode as character xml-node-name "ErrorCode"
field ErrorDescription as character xml-node-name "ErrorDescription"
field FileId as character xml-node-name "FileId".
define dataset Envelope for ttBody, ttUploadResponse.
define variable vGUID as character no-undo.
assign vGUID = guid.
/* Erzeugt das SOAP-QUERY für UploadFile */
oRequestBody = '<soapenv:Envelope xmlns:soapenv="schemas.xmlsoap.org/.../" xmlns:ser="services.kinetic.ch/">' + CRLF +
'<soapenv:Header>' + CRLF +
'<ser:Length>' + string(cLength) + '</ser:Length>' + CRLF +
'<ser:FileName>' + cFileName + '</ser:FileName>' + CRLF +
'</soapenv:Header>' + CRLF +
'<soapenv:Body>' + CRLF +
'<ser:RemoteFileInfo>' + CRLF +
'<ser:Content>' + '<xop:Include href="cid:Data" xmlns:xop="www.w3.org/.../>' + '</ser:Content>' + CRLF +
'</ser:RemoteFileInfo>' + CRLF +
'</soapenv:Body>' + CRLF +
'</soapenv:Envelope>'.
oBody = ByteBucket:Instance().
oBody:PutString(oRequestBody).
oBody:PutString(CRLF).
assign oEntity = new MultipartEntity()
oEntity:Boundary = vGUID
oPart = new MessagePart('application/xop+xml; charset=UTF-8; type="text/xml"':u, oBody).
oPart:Headers:Put(HttpHeaderBuilder:Build('Content-Transfer-Encoding':u)
:Value("8Bit")
:Header).
oPart:Headers:Put(HttpHeaderBuilder:Build('Content-ID':u)
:Value("<DataFile>")
:Header).
/* Das SOAP-HEADER ist das erste Part des QUERY */
oEntity:AddPart(oPart).
oFile = ByteBucket:Instance().
set-size(mData) = 0.
copy-lob file cFilePath + cFileName to mData.
oFile:PutBytes(mData).
oFilePart = new MessagePart('application/base64; name=file64.pdf':u, oFile).
oFilePart:Headers:Put(HttpHeaderBuilder:Build('Content-Transfer-Encoding':u)
:Value("binary")
:Header).
oFilePart:Headers:Put(HttpHeaderBuilder:Build('Content-ID':u)
:Value("<Data>")
:Header).
oFilePart:Headers:Put(HttpHeaderBuilder:Build('Content-Disposition':u)
:Value('attachment; name="file64.pdf"; filename="file64.pdf"')
:Header).
/* Die Datei zu senden ist das zweite Part des QUERY */
oEntity:AddPart(oFilePart).
oRequest = RequestBuilder:Post("http://adresse_to_wsdl", oEntity)
:ContentType('multipart/related; type="application/xop+xml"; start="<DataFile>"; start-info="text/xml"; boundary="' + vGUID + '"')
:AddHeader('SOAPAction', 'adresse_to_WS/UploadFile')
:AddHeader('Accept-Encoding', 'gzip,deflate')
:AddHeader('MIME-Version', '1.0')
:AddHeader('Connection', 'Keep-Alive')
:Request.
oResponse = ClientBuilder:Build()
:Client:Execute(oRequest).
/* Die Antwort ist auch in Multipart */
/* SOAP-RESPONSE Beispiel :
<?xml version="1.0" encoding="UTF-8" ?>
<s:Envelope xmlns:s="schemas.xmlsoap.org/.../">
<s:Body>
<UploadResponse xmlns="services.kinetic.ch/">
<ErrorCode>0</ErrorCode>
<ErrorDescription/>
<FileId>7bdab683-2c79-48e2-b051-b1b8dd628934</FileId>
</UploadResponse>
</s:Body>
</s:Envelope>
*/
oResponseMultipartEntity = cast(oResponse:Entity,OpenEdge.Net.MultipartEntity).
/* Grab the last part of the multi-part message and put it in a memptr */
oMessagePart = oResponseMultipartEntity:GetPart(oResponseMultipartEntity:Size).
oByteBucket = cast(oMessagePart:Body,OpenEdge.Core.ByteBucket).
oResponseMemptrEntity = oByteBucket:GetBytes().
copy-lob from oResponseMemptrEntity:Value to cResponse.
create x-document hXDoc.
cSoapHeader = cResponse.
lcUTF-8 = codepage-convert(cSoapHeader, 'UTF-8').
hXDoc:load('LONGCHAR', lcUTF-8, false).
hXDoc:encoding = 'UTF-8'.
Set-Size(mData) = 0.
HxDoc:save('LONGCHAR',cSoapHeader).
dataset Envelope:read-xml( "longchar", cSoapHeader, ? , ?, ? ).
/* Es gibt nur ein FileId zu lesen */
for each ttUploadResponse:
if ttUploadResponse.ErrorCode <> "0" then do:
message "Error : " skip
ttUploadResponse.ErrorDescription
view-as alert-box.
return ?.
end.
FileId = ttUploadResponse.FileId.
end.
Nice! Thanks for sharing.
Hi,
I'm just trying to run this code with OpenEdge 11.7.2.
2 years ago this code was ok and I got the response back, like in the example.
Now, with OE11.7.2, I get the response back, but oResponseMultipartEntity:Size) is empty.
I found in the Progress KB this article : knowledgebase.progress.com/.../invalid-cast-from-openedge-core-widgethandle-to-openedge-net-multipartentity
I tryed to implement it, but with no success....
Did somebody used my previous code ? Dis somebody know how to extract the xml-part of the http-response in a lonchar ?