How to get SOAP-REPONSE to manipualte it ?

Posted by Samuel ETTERLEN on 25-Aug-2016 08:55

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

All Replies

Posted by Peter Judge on 25-Aug-2016 09:02

This is a multipart message response. I don’t believe the SOAP client can consume these.
 
Depending on your OE version you should be able to use the HttpClient (11.6+).

Posted by Samuel ETTERLEN on 25-Aug-2016 09:06

Hi Peter,

My OE Version is 11.6.2... What I don't understand, is that SoapUI (for example) can correctly read the response ....

Posted by Mike Fechner on 25-Aug-2016 09:10

It’s a limitation of the SOAP client built into the Progress runtime.
 
 

Posted by Samuel ETTERLEN on 25-Aug-2016 09:10

But you are right :

knowledgebase.progress.com/.../P148513

Thanks !

Posted by Samuel ETTERLEN on 29-Aug-2016 09:03

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.

Posted by Peter Judge on 29-Aug-2016 10:57

Nice! Thanks for sharing.

Posted by Samuel ETTERLEN on 18-Jun-2018 10:43

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 ?

This thread is closed