Разбор сырого мтома для построения файла - PullRequest
0 голосов
/ 12 апреля 2019

Каким-то образом я столкнулся с проблемой использования конечной точки SOAP со страницей aspx, которая запускает vb. Отправка файлов и простых данных работает, но я застрял при загрузке файла снова.

Для ответа MTOM я просто проверяю содержимое в и анализирую его как XElement, который работает. Теперь для двоичного потока я попробовал то же самое, но пока не увенчался успехом. Ниже приведен код для вызова конечной точки и получения результата.

Private Function sendSOAPRequest(url As String, enpoint As String, data As Byte()) As String
            Dim result As String = ""
            Try
                Dim req = WebRequest.Create(url)
                req.Headers.Add("SOAPAction", url + enpoint)

                req.ContentType = "application/soap+xml"
                req.ContentLength = data.Length
                req.Method = "POST"

                Dim DataStream = req.GetRequestStream()
                DataStream.Write(data, 0, data.Length)
                DataStream.Close()

                Dim WebResponse = req.GetResponse()
                Dim resp = WebResponse.GetResponseStream()
                Dim Reader = New StreamReader(resp)
                result = Reader.ReadToEnd()

                DataStream.Close()
                Reader.Close()
                resp.Close()
            Catch ex As WebException
                System.Diagnostics.Debug.WriteLine(ex.ToString())
            End Try
            System.Diagnostics.Debug.WriteLine(result)
            Return result

        End Function

Теперь для входа / выхода / загрузки это работает. Теперь для некоторого вызова fileContent я получаю это обратно:

HTTP/1.1 200 OK
X-Powered-By: Undertow/1
Access-Control-Allow-Headers: accept, authorization, content-type, x-requested-with
Server: WildFly/10
Date: Fri, 12 Apr 2019 12:06:58 GMT
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Content-Type: multipart/related; type="application/xop+xml"; boundary="uuid:6c8ac7c2-cac9-437f-a319-72c7c0e60328"; start="<root.message@cxf.apache.org>"; start-info="application/soap+xml"
Content-Length: 5371
Access-Control-Max-Age: 1
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT

--uuid:6c8ac7c2-cac9-437f-a319-72c7c0e60328
Content-Type: application/xop+xml; charset=UTF-8; type="application/soap+xml"
Content-Transfer-Encoding: binary
Content-ID: <root.message@cxf.apache.org>

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Body><ns2:getContentObjectStreamResponse xmlns:ns2="http://ws.soap.transfer.services.sedna.ser.com/"><dataHandler><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:a31b1e84-b3a5-4482-90af-f99943ec08a2-9@cxf.apache.org"/></dataHandler></ns2:getContentObjectStreamResponse></soap:Body></soap:Envelope>
--uuid:6c8ac7c2-cac9-437f-a319-72c7c0e60328
Content-Type: */*
Content-Transfer-Encoding: binary
Content-ID: <a31b1e84-b3a5-4482-90af-f99943ec08a2-9@cxf.apache.org>

‰PNG
binary data
--uuid:6c8ac7c2-cac9-437f-a319-72c7c0e60328--

Как я могу разобрать только двоичную часть и вернуть файл?

Обновление 16.04.2019: я получил содержимое со следующими строками:

Dim rContent As New System.Text.RegularExpressions.Regex("(?<=Content-ID: <[^root].*[>])(.|\n)*(?=--uuid)")
Dim matchContent As Match = rContent.Match(documentResponse)
Dim documentContentData As String = matchContent.Value

Но похоже, что преобразование String как-то портит двоичное кодирование. Запись этого содержимого в файл с

Dim fileBytes As Byte() = UnicodeStringToBytes(trimmedContent)
File.WriteAllBytes("C:\Path\cloud.png", fileBytes)

больше исходного файла и в неправильной кодировке.

1 Ответ

0 голосов
/ 17 апреля 2019

Я нашел решение, которое не изящно и не рекомендуется Разбирайте ответный байт на байт и просто копируйте двоичную часть, обрезая конверт и вмещая сообщение (методом проб и ошибок). Теперь давайте просто надеяться, что конечная точка никогда не изменит этот формат.

        Private Function getSoapFileBytes(url As String, endpoint As String, data As Byte()) As Byte()
            Dim result As String = ""
            Dim fileBytes As New List(Of Byte)
            Try
                Dim req = WebRequest.Create(url)
                req.Headers.Add("SOAPAction", url + endpoint)

                req.ContentType = "application/soap+xml"
                req.ContentLength = data.Length
                req.Method = "POST"

                Dim DataStream = req.GetRequestStream()
                DataStream.Write(data, 0, data.Length)
                DataStream.Close()

                Dim WebResponse = req.GetResponse()

                Dim resp = WebResponse.GetResponseStream()

                Dim contentList As New List(Of Byte)
                Dim ct As Byte() = New Byte() {}

                Dim currentByte As Integer = 0
                While currentByte > -1
                    currentByte = resp.ReadByte()
                    Dim myByte = BitConverter.GetBytes(currentByte)
                    ct.Concat(myByte)
                    contentList.Add(myByte.ElementAt(0))
                End While


                Dim fb As Byte() = New Byte() {}

                For c As Integer = 772 To (contentList.Count - 49)
                    fileBytes.Add(contentList.ElementAt(c))
                Next

                DataStream.Close()
                resp.Close()
            Catch ex As WebException
                System.Diagnostics.Debug.WriteLine(ex.ToString())
            End Try
            System.Diagnostics.Debug.WriteLine(result)
            Return fileBytes.ToArray()

        End Function
...