How to get SOAP-REPONSE to manipualte it ? - Forum - OpenEdge Development - Progress Community

How to get SOAP-REPONSE to manipualte it ?

 Forum

How to get SOAP-REPONSE to manipualte it ?

  • 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

  • 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+).
  • Hi Peter,

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

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

    Architect of the SmartComponent Library and WinKit

    Consultingwerk Ltd.

  • But you are right :

    knowledgebase.progress.com/.../P148513

    Thanks !

  • 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 ?