Attachments using REST WebService and VB.NET

2019-08-04 04:10发布

问题:

I am currently developing an application using VB.NET in which I am using the REST WebServices. I have been able to do the basics with REST, however, I have not been able to add an attachment (more specifically upload a file, using REST which gets attached). I have done extensive research online, but so far I have not been able to find any working examples in VB.NET. To actually upload the data I use System.Net.WebClient. The following VB.NET code does the important work:

Dim Client As New System.Net.WebClient
Dim postBytes As Byte() = System.Text.Encoding.ASCII.GetBytes(postString)
Client.UploadData(URL, "POST", postBytes)

A simplified version of my URL is as follows: "../REST/1.0/ticket/" + ticketNumber + "/comment?user=" + userName + "&pass=" + password

Finally, an example of the content that I post is:

postString = "content=Text: RT Test" + vbLf + "Action: Comment" + vbLf + "Attachment: examplefile.jpg" + vbLf + "attachment_1="

As you can see, the postString is converted to bytes and then uploaded to the server. However, I do not know where or how I should be posting the raw attachment itself. The documentation for the service we are specifically using states to use a variable "attachment_1," which I added to the postString variable, but I am not sure what the next step should be. Should the file be converted into bytes and appended to the postBytes variable? I attempted something like this but I received an error saying that no attachment was found for examplefile.jpg.

Thanks for your help!

回答1:

We could not use Client.UploadData(...) and had to convert the entire post to bytes, starting with the POST fields before the attachment, then the attachment itself, and finally the remainder of the POST fields.

Public Sub AddAttachmentToRT(ByVal url As String, ByVal fileName As String, ByVal filePath As String)

    Dim dataBoundary As String = "--xYzZY"
    Dim request As HttpWebRequest
    Dim fileType As String = "image/jpeg" 'Will want to extract this to make it more generic from the uploaded file.

    'Create a POST web request to the REST interface using the passed URL
    request = CType(WebRequest.Create(url), HttpWebRequest)
    request.ContentType = "multipart/form-data; boundary=xYzZY"
    request.Method = "POST"
    request.KeepAlive = True

    'Write the request to the requestStream
    Using requestStream As IO.Stream = request.GetRequestStream()

        'Create a variable "attachment_1" in the POST, specify the file name and file type
        Dim preAttachment As String = dataBoundary + vbCrLf _
        + "Content-Disposition: form-data; name=""attachment_1""; filename=""" + fileName + """" + vbCrLf _
        + "Content-Type: " + fileType + vbCrLf _
        + vbCrLf

        'Convert this preAttachment string to bytes
        Dim preAttachmentBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(preAttachment)

        'Write this preAttachment string to the stream
        requestStream.Write(preAttachmentBytes, 0, preAttachmentBytes.Length)

        'Write the file as bytes to the stream by passing its exact location
        Using fileStream As New IO.FileStream(Server.MapPath(filePath + fileName), IO.FileMode.Open, IO.FileAccess.Read)

            Dim buffer(4096) As Byte
            Dim bytesRead As Int32 = fileStream.Read(buffer, 0, buffer.Length)

            Do While (bytesRead > 0)

                requestStream.Write(buffer, 0, bytesRead)
                bytesRead = fileStream.Read(buffer, 0, buffer.Length)

            Loop

        End Using

        'Create a variable named content in the POST, specify the attachment name and comment text
        Dim postAttachment As String = vbCrLf _
        + dataBoundary + vbCrLf _
        + "Content-Disposition: form-data; name=""content""" + vbCrLf _
        + vbCrLf _
        + "Action: comment" + vbLf _
        + "Attachment: " + fileName + vbCrLf _
        + "Text: Some description" + vbCrLf _
        + vbCrLf _
        + "--xYzZY--"

        'Convert postAttachment string to bytes
        Dim postAttachmentBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(postAttachment)

        'Write the postAttachment string to the stream
        requestStream.Write(postAttachmentBytes, 0, postAttachmentBytes.Length)

    End Using

    Dim response As Net.WebResponse = Nothing

    'Get the response from our REST request to RT
    'Required to capture response, without this Try-Catch attaching will fail
    Try
        response = request.GetResponse()

        Using responseStream As IO.Stream = response.GetResponseStream()

            Using responseReader As New IO.StreamReader(responseStream)

                Dim responseText = responseReader.ReadToEnd()

            End Using

        End Using

    Catch exception As Net.WebException

        response = exception.Response

        If (response IsNot Nothing) Then

            Using reader As New IO.StreamReader(response.GetResponseStream())

                Dim responseText = reader.ReadToEnd()

            End Using

            response.Close()

        End If

    Finally

        request = Nothing

    End Try

End Sub