1

I am attempting to send an attachment through a HttpWebRequest in a Console Application. After a few days of searching and scouring the internet for some understandable assistance on this, I came up with what I think is a decent solution from this site

While I think I've done everything correctly, I am receiving the following error:

Multipart stream ended before a terminating boundary was encountered.

Questions:
I'm hoping to get some assistance/guidance with the multipart error I'm receiving, as well as assistance in attaching the actual byte[] of the XML Document.

Requirements:

  1. The data file that needs to be attached is is an XML file which should be an MTOM Attachment. In order to make it Mtom, my understanding is that I need to be sure that the messageEncoding attribute of the <binding> element in the app.config should have a value of "Mtom" and this will be encoded as such.
  2. Based on the business requirements (of which is strict), I need to send the byte[] of the file, not simply the contents itself.

Web Request Method

private static HttpWebRequest CreateWebRequest(SoapAction action)
{
    // Retrieve URL from Endpoint in the app.Config based on the action passed into the
    // method.
    string url = GetUrlAddress(action);

    if (url != null)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

        request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
        request.Headers.Add(HttpRequestHeader.ContentEncoding, "gzip");
        request.Headers.Add("Content-Transfer-Encoding", "8bit");
        request.Headers.Add("SOAPAction", action.ToString());

        request.Method = "POST";

        request.Headers.Add("MIME-Version", "1.0");
        request.ContentType = "multipart/form-data; type=\"application/xop+xml;\" boundary=\"" + BoundaryMarker + "\"";

        request.ClientCertificates.Add(SecurityCertificate.CertificateObject);

        ServicePointManager.Expect100Continue = false;

        return request;
    }
    else
    {
        throw new NullReferenceException("Address for Endpoint could not be resolved.");
    }
}

Method to Submit Request
Based on this post of mine, I believe I am compressing the HttpWebRequest appropriately using GZip.

private static void SubmitRequest(HttpWebRequest request, XDocument soapXml, byte[] formXmlBytes, FileInfo fileToUpload)
{
    using (Stream requestStream = request.GetRequestStream())
    {
        using (GZipStream gz = new GZipStream(requestStream, CompressionMode.Compress, false))
        {
            soapXml.Save(gz);
            WriteToStream(gz, formXmlBytes, fileToUpload.Name);
        }
    }
}

Method used to Write the MIME information and attachment to the Stream

public static void WriteToStream(Stream stream, byte[] formData, string fileName)
    {
        // Write a new line to the stream.
        byte[] newLineBytes = Encoding.UTF8.GetBytes("\r\n");
        stream.Write(newLineBytes, 0, newLineBytes.Length);

        // Write the header to the stream.
        string header = String.Format(HeaderTemplate, BoundaryMarker, fileName, RequestContentID);
        byte[] headerBytes = Encoding.UTF8.GetBytes(header);
        stream.Write(headerBytes, 0, headerBytes.Length);

        // Write a new line to the stream.
        stream.Write(newLineBytes, 0, newLineBytes.Length);

        // Write the formData to the stream.
        stream.Write(formData, 0, formData.Length);

        // Write a new line to the stream.
        stream.Write(newLineBytes, 0, newLineBytes.Length);

        // Write the footer to the stream.
        byte[] boundaryFooterBytes = Encoding.UTF8.GetBytes("--" + BoundaryMarker + "--");
        stream.Write(boundaryFooterBytes, 0, boundaryFooterBytes.Length);
    }

Soap Body Snippet Element
By using Fiddler, I am able to see what the request actually looks like. To me, it appears that the attachment is actually being appended to the request as the XML that it is, instead of (what I thought would be) a byte[].

After this should be the byte[] of the attachment. Currently, the full XML document is displaying.

Accept-Encoding: gzip, deflate
Content-Transfer-Encoding: 8bit
MIME-Version: 1.0
Content-Type: multipart/form-data; type="application/xop+xml;" boundary="--b73acdd180274cab985e4d697bfde428"
Content-Length: 582081
Connection: Keep-Alive

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="..." ...>
...
<soapenv:Body>
    <urn:Request version="1.0">
        <urn:FileAttachment>cid:b73acdd180274cab985e4d697bfde428</urn:FileAttachment>
    </urn:Request>
</soapenv:Body>
</soapenv:Envelope>
----b73acdd180274cab985e4d697bfde428
Content-Disposition: attachment; filename="test.xml"
Content-Type: text/xml
Content-Id: b73acdd180274cab985e4d697bfde428
<XML OF ATTACHMENT>
----b73acdd180274cab985e4d697bfde428--
Community
  • 1
  • 1
Russ
  • 678
  • 8
  • 26
  • Hey, Russ.Looks we both are on same trac. Are u able to send MTOM attachment using C# code? If yes, can u pls share your code snippet or any other example? – Oxygen Mar 15 '16 at 11:58
  • @Oxygen I have a couple of methods to try and work out today. I'll definitely keep you (and the community) posted if I get something working. – Russ Mar 15 '16 at 15:11
  • Thanks Russ. I am trying same and will update you if succeed. – Oxygen Mar 16 '16 at 03:34
  • Hi Russ, no luck yet. You able to make a call using HTTPRequest by forming MTOM attachment? – Oxygen Mar 17 '16 at 07:36
  • @Oxygen No, I am stuck on the error message _The message was not formatted properly and/or cannot be interpreted._ – Russ Mar 17 '16 at 15:16
  • Okay. Are u able to pass WSSecurity in .NET? If yes, then could you pls share some reference of this? We could able to get the receipt in JAVA project but trying in .NET yes. Wanted to have it in .NET because all our application is in .NET; however we can use JAVA project if won't possible in .NET. – Oxygen Mar 18 '16 at 08:40
  • @Oxygen currently, my request is not formatted the way they want it. I am assuming I am past WS-Security errors, however, I cannot be completely sure. Once I get past this, I'll hopefully be able to let you know. [Have you properly signed your request?](http://stackoverflow.com/questions/35735341/malformed-reference-element/35759642#35759642) – Russ Mar 18 '16 at 16:43
  • I have commented formation of MTOM and tried to send just manifest file using HttpRequest which contains WS Security elements formed in .NET but it is giving ws security error. However, if I send a raw manifest generated in SOAP UI using HttpRequest it passes the security part and says MTOM is missing. I have compared both the request's digest value and signatures and both are same but not sure what's getting wrong in .NET code's security formation. Do you have any reference which says A2A WS Security passes in .NET? Or if you have done it already then your snippet pls? – Oxygen Mar 20 '16 at 17:01
  • @Oxygen I am still struggling with getting past [the error outlined here](http://stackoverflow.com/q/36021040/5286901). As far as this processing being do-able in .NET, there are people who have accomplished this feat; so it is not impossible, it just seems more difficult than it probably should/needs to be. – Russ Mar 21 '16 at 15:58
  • @Oxygen any luck on your end in getting any of this to work? – Russ Mar 30 '16 at 18:39
  • I have spent 60 hours in the last week trying to upload an MTOM / MIME document in .Net to an Apache server with no luck so far. In your "Soap Body Snippet Element" there is no MIME boundary before the SOAP section. – Fred Peters Jun 05 '17 at 17:46
  • @FredPeters try https://stackoverflow.com/a/36039647/5286901 It's a year old, however, my solution for sending MTOM / MIME has been working without issues for the past year. I hope you have luck in what you are working on. – Russ Jun 06 '17 at 05:53
  • Dear Can you kindly share your complete code. – faisale Feb 22 '19 at 19:18

0 Answers0