1

I am getting the error:

An error was found while parsing the multipart request. Boundary terminator '--BOUNDARY--' was not found in the request.

I have tried debugging with Firefox and chrome with same results. Any help would be greatly appreciated.

Here is the code I am using:

Public Sub configureMultiPartFormDataRequest(ByVal request As HttpWebRequest, _
                                                 ByVal xmlBody As String, _
                                                 ByVal docName As String)

        'Overwrite the default content-type header and set a boundary marker
        request.ContentType = "multipart/form-data; boundary=BOUNDARY"

        'Start building the multipart request body
        Dim requestBodyStart As String = "\r\n\r\n--BOUNDARY\r\n" + _
            "Content-Type: application/xml\r\n" + _
            "Content-Disposition: form-data\r\n" + _
            "\r\n" + _
            xmlBody + "\r\n\r\n--BOUNDARY\r\n" + _
            "Content-Type: application/pdf\r\n" + _
            "Content-Disposition: file; filename=\" + docName + " \  documentId=1\r\n" + _
            "\r\n"
        Dim requestBodyEnd As String = "\r\n--BOUNDARY--\r\n\r\n"

        'Read the contents of provided document into the request stream
        Dim fileStream As FileStream = File.OpenRead(docName)

        'Write the body of the request
        Dim bodyStart() As Byte = System.Text.Encoding.UTF8.GetBytes(requestBodyStart.ToString())
        Dim bodyEnd() As Byte = System.Text.Encoding.UTF8.GetBytes(requestBodyEnd.ToString())
        Dim dataStream As Stream = request.GetRequestStream()
        dataStream.Write(bodyStart, 0, requestBodyStart.ToString().Length)

        'Read the file contents and write them to the request stream. (4096 Byte Blocks)
        Dim buf(4096) As Byte
        'Dim len As Integer
        'While ((len = fileStream.Read(buf, 0, 4096)) > 0)
        '    dataStream.Write(buf, 0, len)
        'End While
        Dim bytesRead As Integer
        Do
            bytesRead = fileStream.Read(buf, 0, buf.Length)
            If bytesRead > 0 Then
                dataStream.Write(buf, 0, bytesRead)
            End If
        Loop While bytesRead > 0


        dataStream.Write(bodyEnd, 0, requestBodyEnd.ToString().Length)


        dataStream.Close()

    End Sub

Added 05/09/2014 Here is the actual request text from Fiddler2. It appears that the bodyEnd is being set to "PDF-1.7". I have searched the code for this string without success. Thanks for your help: \r\n\r\n--BOUNDARY\r\nContent-Type: application/xml\r\nContent-Disposition: form-data\r\n\r\nsentDocuSign API - Embedded Signing example1\10.1.11.100\SecureDocs\EnrollmentForms\CrystalReport1.pdf1hmitchell@ata.eduA Adams10010011\r\n\r\n--BOUNDARY\r\nContent-Type: application/pdf\r\nContent-Disposition: file; filename=\XXX\; documentId=1\r\n\r\n%PDF-1.7

David Thanks for your fix for the BOUNDARY error. I implemented your xml example and now get an error: "The document element did not contain the encoded document, or there is a problem with the encoding." Here is the request: --BOUNDARY Content-Type: application/xml Content-Disposition: form-data

sentDocuSign API - Embedded Signing example1C:\Hold\myXML.xml1hmitchell@ata.eduA Adams10010011

--BOUNDARY Content-Type: application/pdf Content-Disposition: file; filename=\C:\Hold\myXML.xml \ documentId=1

    <nameValue>
        <name>canManageAccount</name>
        <value>false</value>
    </nameValue>

--BOUNDARY--

Thanks for your help!!!

Hugh
  • 17
  • 1
  • 7
  • shouldn't your `Content-Disposition: form-data` be `Content-Disposition: application/xml`? can you post the data that `dataStream.Write` is compiling? – Andrew May 08 '14 at 18:57
  • I think the content-disposition is set correctly, however as Andrew has asked it would be most helpful if you post the actual request text that this code creates and sends out... – Ergin May 08 '14 at 19:57
  • Ergin's right. I need to drink Coffee before answering Stack Overflow :) – Andrew May 09 '14 at 15:18
  • Ah, I see this issues. 1. Add back your JSON/XML body and your PDF. Don't try and escape the file name, you don't need to the path in the multipart file aka filename=\C:\Hold\myXML.xml \ should be yourfilename.pdf my files where just to make the sample simple to understand and the code change for the New Line and Carriage returns can't be escaped that way in VB.NET – David W Grigsby May 16 '14 at 15:08
  • Also, please start new questions about new problems, instead of follow ons on this question so that it is clearer for others in the community about what the original question was and what the answer was, so thanks for your help in following this best practice. Happy Coding! – David W Grigsby May 16 '14 at 15:20
  • Oh and please mark that it answered your question and upvote the answer that helped resolve your question and issue. – David W Grigsby May 16 '14 at 15:21
  • Thanks again David! I tried to upvote your answer but I require 15 reputation??? Also, does the green check mark indicate you solved the original problem? – Hugh May 16 '14 at 17:07
  • Green Check - Yes Solved - THank you and upvote, you will have 15 rep soon enough :-) – David W Grigsby May 19 '14 at 17:32

2 Answers2

1

Your code snippet above is missing the calling method so I made my own as shown below to demonstrate how to leverage WebHookapp endpoint to capture what is being sent. So I think you will see that the body is not formatted correctly due to the fact you tried to "escape" the line breaks and carriage return values vs using the chr with the correct value.

Code I added to call you above method

Imports System.IO
Imports System.Net

Public Class Form1

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click

    Dim myHTTPRequest As System.Net.HttpWebRequest = WebRequest.Create("http://webhookapp.com/1037371688646089664")
    Dim myXML As String = "{SomeXMLorJason: sampleNotFormatedcorrectly}"
    Dim myDocName As String = "c:\myXML.xml"
    myHTTPRequest.Method = "POST"

    configureMultiPartFormDataRequest(myHTTPRequest, myXML, myDocName)


    myHTTPRequest.GetResponse()

End Sub

'Your Code goes here ---> from above:

End Class

What is in the file c:\myXML.xml

        <nameValue>
            <name>canManageAccount</name>
            <value>false</value>
        </nameValue>

What was sent:

POST /1037371688646089664
content-type    multipart/form-data; boundary=BOUNDARY
host    webhookapp.com
content-length  439
expect  100-continue
connection  Keep-Alive
\r\n\r\n--BOUNDARY\r\nContent-Type: application/xml\r\nContent-Disposition: form-data\r\n\r\n{SomeXMLorJason: sampleNotFormatedcorrectly}\r\n\r\n--BOUNDARY\r\nContent-Type: application/pdf\r\nContent-Disposition: file; filename=\c:\myXML.xml \  documentId=1\r\n\r\n                <nameValue>
                    <name>canManageAccount</name>
                    <value>false</value>
                </nameValue>\r\n--BOUNDARY--\r\n\r\n

What to do to fix your code:

 'Start building the multipart request body
        ' http://www.asciitable.com/

        Dim asciLN As String = Chr(10)
        Dim asciCR As String = Chr(13)

        Dim requestBodyStart As String = asciCR + asciLN + asciCR + asciLN + "--BOUNDARY" + asciCR + asciLN + _
            "Content-Type: application/xml" + asciCR + asciLN + _
            "Content-Disposition: form-data" + asciCR + asciLN + _
            asciCR + asciLN + _
            xmlBody + asciCR + asciLN + asciCR + asciLN + "--BOUNDARY" + asciCR + asciLN + _
            "Content-Type: application/pdf" + asciCR + asciLN + _
            "Content-Disposition: file; filename=\" + docName + " \  documentId=1" + asciCR + asciLN + _
            asciCR + asciLN
        Dim requestBodyEnd As String = asciCR + asciLN + "--BOUNDARY--" + asciCR + asciLN + asciCR + asciLN

Which will yield:

POST /1037371688646089664
content-type    multipart/form-data; boundary=BOUNDARY
host    webhookapp.com
content-length  409
expect  100-continue
connection  Keep-Alive

--BOUNDARY
Content-Type: application/xml
Content-Disposition: form-data

{SomeXMLorJason: sampleNotFormatedcorrectly}

--BOUNDARY
Content-Type: application/pdf
Content-Disposition: file; filename=\c:\myXML.xml \  documentId=1

                <nameValue>
                    <name>canManageAccount</name>
                    <value>false</value>
                </nameValue>
--BOUNDARY--

And a general envelope in JSON as Multipart should look like below:

POST http://{server}/restapi/{apiVersion}/accounts/{accountId}/envelopes

X-DocuSign-Authentication: <DocuSignCredentials><Username>{name}</Username><Password>{password}</Password><IntegratorKey>{integrator_key}</IntegratorKey></DocuSignCredentials>
Accept: application/json
Content-Type: multipart/form-data; boundary=AAA

--AAA
Content-Type: application/json
Content-Disposition: form-data
{
  "status":"sent",
  "emailBlurb":"Test Email Body",
  "emailSubject": "Test Email Subject - EnvelopeDefFull",
  "documents": [{
      "name": "test1.pdf",
      "documentId":"1"
      "order":"1"
  }],
  "recipients": {
    "signers" : [{
      "email": "test@email.com",
      "name": "Sally Doe",
      "recipientId":"1",
    }]
  }
}
--AAA
Content-Type: application/pdf
Content-Disposition: file; filename="test1.pdf";documentid=1

<document bytes removed>

--AAA--
David W Grigsby
  • 1,554
  • 1
  • 13
  • 23
  • David, Thanks for solving the BOUNDARY problem. I implemented you test example and I now receive a "No Document Received" error. Next comment is the request: – Hugh May 16 '14 at 13:13
-1

Generally speaking your request should look like the following. The only difference is that this example used JSON format instead of XML. Only change you need to make is changing application/json to application/xml for the Content-Type, then change the JSON data to XML format instead.

POST http://{server}/restapi/{apiVersion}/accounts/{accountId}/envelopes

X-DocuSign-Authentication: <DocuSignCredentials><Username>{name}</Username><Password>{password}</Password><IntegratorKey>{integrator_key}</IntegratorKey></DocuSignCredentials>
Accept: application/json
Content-Type: multipart/form-data; boundary=AAA

--AAA
Content-Type: application/json
Content-Disposition: form-data
{
  "status":"sent",
  "emailBlurb":"Test Email Body",
  "emailSubject": "Test Email Subject - EnvelopeDefFull",
  "documents": [{
      "name": "test1.pdf",
      "documentId":"1"
      "order":"1"
  }],
  "recipients": {
    "signers" : [{
      "email": "test@email.com",
      "name": "Sally Doe",
      "recipientId":"1",
    }]
  }
}
--AAA
Content-Type: application/pdf
Content-Disposition: file; filename="test1.pdf";documentid=1

<document bytes removed>

--AAA--

Without seeing the actual request that your code is constructing and sending I can only assume something is wrong with the formatting. Ensure that you have extra newlines (CRLF) where needed and that the document bytes are correctly being written to the request. If you're still stuck you might want to run through a tool such as Fiddler to check the request data...

Ergin
  • 9,254
  • 1
  • 19
  • 28