3

Hy!

I'm developing a C# SOAP service to communicate with one of our governmental services. They also use SOAP for communication, but now they introduced two new endpoints that handle requests very differenty. The first thing that I noticed is that when I called $SoapClient->Request(...) from the PHP code of the client app, it failed with the error Looks like we got no XML document. The only way to get the actual response is to try-catch the SoapFault and then call$response = $SoapClient->__getLastResponse() to read it. It was indeed not an xml, but a binary format, kind of like the source of E-mail attachments.

After I figured it out, and downloaded the PDF file, it was still malformed. First I think that PHP is messing up something, but then I looked at the logs of the WebService and it was already malformed. I tried many different encodings with StreamReader, with no luck. Then I changed it to BinaryReader for that two endpoints. It's now way closer to the response I'm looking for, but still, there are seemingly random garbage characters included, like shown on this screenshot:

The left side is what I'm looking for, and the right is what I got. enter image description here

My code:

string soapResult;
try
{
    using (HttpWebResponse webResponse = (HttpWebResponse)httpRequest.EndGetResponse(asyncResult))
    {
        if (request == "edoc/getDocument" || request == "edoc/downloadFile")
        {
            using (BinaryReader rd = new BinaryReader(webResponse.GetResponseStream()))
            {
                soapResult = Encoding.Default.GetString(rd.ReadBytes(10000000));
            }
        }
        else
        {
            using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
            {
                soapResult = rd.ReadToEnd();
            }
        }
    }
}
...

How can I overcome this? I'm struggling for days now, but can't figure out what's wrong...

EDIT: The actual response looks exactly like this:

--MIME_Boundary
Content-ID: <c907fb5b-7aa7-4556-88fd-5074f43aafbb>
Content-Type: application/xop+xml; type="text/xml"; charset=UTF-8
Content-Transfer-Encoding: 8bit

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><env:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsu:Timestamp wsu:Id="Timestamp-JAuOpC673QOitIDD7tlAuA22" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><wsu:Created>2021-08-19T12:00:14Z</wsu:Created><wsu:Expires>2021-08-19T12:05:14Z</wsu:Expires></wsu:Timestamp></wsse:Security></env:Header><env:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><ns10:getDocument xmlns="http://eeszt.gov.hu/ns/common/ws/messageHeaderTypes/v3" xmlns:ns2="http://eeszt.gov.hu/ns/common/cdm/v3" xmlns:ns3="http://eeszt.gov.hu/ns/common/ws/messageTypes/v3" xmlns:ns4="http://eeszt.gov.hu/ns/eDoc/ws/eDocService/v1" xmlns:ns5="http://eeszt.gov.hu/ns/eDoc/ws/eDocService/messages/v1" xmlns:ns6="http://eeszt.gov.hu/ns/eDoc/ws/eDocService/Request/v1" xmlns:ns7="http://eeszt.gov.hu/ns/documentrenderer/ws/common/messages/v1" xmlns:ns8="http://eeszt.gov.hu/ns/common/ws/queryTypes/v3" xmlns:ns9="http://eeszt.gov.hu/ns/common/ws/errorTypes/v3" xmlns:ns10="http://eeszt.gov.hu/ns/eDoc/ws/eDocService/Response/v1" xmlns:ns11="http://eeszt.gov.hu/ns/common/ws/versionInfoTypes/v3" xmlns:ns12="http://eeszt.gov.hu/ns/documentrenderer/ws/DocumentRendererService"><ns10:getDocumentResponse><ns3:businessMessageHeader><initiator><userId>O60547</userId><userName>Dr. Psyklon</userName><clientUserId>O60547</clientUserId><applicationId>DokiRex.NET:v1.57</applicationId><applicationName>DokiRex.NET</applicationName><applicationFunction>edoc_get_document</applicationFunction><organizationId>E200158</organizationId><organizationName>Asd</organizationName><organizationUnitId>002001581</organizationUnitId><organizationUnitName>Eeszt Dev</organizationUnitName></initiator><representedUser><userId>O60547</userId><userName>Orvos 1 DEV69</userName><clientUserId>O60547</clientUserId></representedUser><initiatorCitizen><ns2:citizenIDs><ns2:citizenID><ns2:type>1</ns2:type><ns2:id>900200018</ns2:id></ns2:citizenID></ns2:citizenIDs></initiatorCitizen><representedCitizen><ns2:citizenIDs><ns2:citizenID><ns2:type>1</ns2:type><ns2:id>900200018</ns2:id></ns2:citizenID></ns2:citizenIDs></representedCitizen><logging><submittedAt>2021-08-19T14:00:14.156+02:00</submittedAt><EESZTLogging><receivedAt>2021-08-19T14:00:14.147+02:00</receivedAt><processedAt>2021-08-19T14:00:14.234+02:00</processedAt><EESZTtransactionId>0aa47ec3-ad01-4a37-b75b-121c2f645a1c</EESZTtransactionId></EESZTLogging></logging></ns3:businessMessageHeader><ns3:status>OK</ns3:status><ns5:businessMessageContent><ns5:eDoc><ns4:id>11953</ns4:id><ns4:docType>ack</ns4:docType><ns4:docTypeName>Kézbesítés igazolás</ns4:docTypeName><ns4:docNev>Kézbesítés igazolás</ns4:docNev><ns4:docStatusz>REND</ns4:docStatusz><ns4:docStatuszName>Renderelt</ns4:docStatuszName><ns4:docFeltoltoIntezmeny>E200006</ns4:docFeltoltoIntezmeny><ns4:docFeltoltoSzervezetiEgyseg>002000061</ns4:docFeltoltoSzervezetiEgyseg><ns4:docFeltoltoUser>O60017</ns4:docFeltoltoUser><ns4:docFelelosUser>O60017</ns4:docFelelosUser><ns4:allampolgar><ns2:type>1</ns2:type><ns2:id>900200018</ns2:id></ns4:allampolgar><ns4:feltoltesIdeje>2021-06-23T19:12:52.308+02:00</ns4:feltoltesIdeje><ns4:tarolasiIdo>2021-10-01T19:12:52.000+02:00</ns4:tarolasiIdo><ns4:forrasDocId>11952</ns4:forrasDocId><ns4:parentDocId>11952</ns4:parentDocId><ns4:attachments><ns4:attachmentResponse><ns4:id>29625</ns4:id><ns4:name>kezbesitesi_jelentes.pdf</ns4:name><ns4:mimeType>application/pdf</ns4:mimeType><ns4:file><inc:Include href="cid:[email protected]" xmlns:inc="http://www.w3.org/2004/08/xop/include"/></ns4:file></ns4:attachmentResponse></ns4:attachments><ns4:recipients/><ns4:linkedDocuments/></ns5:eDoc></ns5:businessMessageContent></ns10:getDocumentResponse></ns10:getDocument></env:Body></soapenv:Envelope>
--MIME_Boundary
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-ID: <[email protected]>

%PDF-1.4
%ª«¬­
1 0 obj
<<
/Creator (Apache FOP Version 2.3)
/Producer (Apache FOP Version 2.3)
/CreationDate (D:20210623191252+02'00')
>>
endobj
2 0 obj
<<
  /N 3
  /Length 3 0 R
  /Filter /FlateDecode
>>
stream
xœí™gPTY€ï{
ÝM“¡ÉI¢„$ç$A²¨@w“i¡ÉAQdpFIŠ ¢€ŽAFQÅ€(( ¢N#ƒ€2Ž"**KãÙ­
...
8
  • 3
    Encoding.Default is really suspicious. Do you know what encoding is used by the downstream system? I mean does the SOAP response define the encoding? Commented Aug 26, 2021 at 14:47
  • 2
    I tried almost all of them (Unicode, UTF8, UTF7, ASCII) but those all look even worse. Commented Aug 27, 2021 at 4:29
  • 2
    No beacuse it's not an XML. It contains multiple files separated with a --MIME_Boundary. The following headers are for the PDF I'm interested in: --MIME_Boundary Content-Type: application/octet-stream Content-Transfer-Encoding: binary Commented Aug 27, 2021 at 8:20
  • 4
    Maybe you need to use the MultipartMemoryStreamProvider. See this thread Commented Aug 30, 2021 at 8:22
  • 2
    Could you write the raw response to a file? Then you may be able to use a HEX-editor to compare the files and see the difference. Commented Sep 2, 2021 at 19:21

2 Answers 2

2
+50

You are getting a multipart response so you need to parse it to get the parts. I will provide a sample a solution using the Microsoft.AspNet.WebApi.Client NuGet package that includes extension methods for easier processing of such content. Since you use the old now obsolete HttpWebRequest you need first to transform the stream you get to a HttpContent object and then you can get a MultipartMemoryStreamProvider object from it using the extension method ReadAsMultipartAsync. This object has an array of contents so you can read each of the parts.

Here is your code changed to read the PDF part as string.

string soapResult;
using (HttpWebResponse webResponse = (HttpWebResponse)httpRequest.EndGetResponse(asyncResult))
{
   StreamContent streamContent = new StreamContent(webResponse.GetResponseStream());
   streamContent.Headers.Add("Content-Type", webResponse.ContentType);

   MultipartMemoryStreamProvider? multipart = await streamContent.ReadAsMultipartAsync();

   soapResult = await multipart.Contents[1].ReadAsStringAsync(); // read second content that has index 1
}

I would suggest you change your code to use the newer HttpClient to do web requests and then this code becomes even more simple.

string soapResult;
using (HttpClient httpClient = new HttpClient()) // For best performance you should create one HttpClinet for all the application and reuse it for all calls not create new for each call.
{
   using (HttpResponseMessage? httpResponseMessage = await httpClient.GetAsync("https://localhost:5001/api/multipart"))
   {
      MultipartMemoryStreamProvider? multipart = await httpResponseMessage.Content.ReadAsMultipartAsync();

      soapResult = await multipart.Contents[1].ReadAsStringAsync();
   }
}


  
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, your solution pointed me to the right direction. I only changed ReadAsStringAsync() to ReadAsByteArrayAsync() and wrapped it in Convert.ToBase64String, so now I'm able to get a valid XML response on the other end, and just display the pdf with base64_decode.
2

Do not read binary content as string via any Encoding. A raw PDF content is not conform to any encoding so your string result will be corrupt for sure.

If you need to return a binary content as text in your SOAP message, then use base64 encoding instead:

// binary content: as base64
if (webResponse.ContentType == "application/octet-stream")
    soapResult = Convert.ToBase64String(br.ReadBytes((int)webResponse.ContentLength));

And the receiver of your SOAP message can restore the original binary content by Convert.FromBase64String.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.