使用REST WebService和VB.NET的附件

问题描述

| 我目前正在使用VB.NET开发一个应用程序,其中正在使用REST WebServices。我已经能够使用REST进行基础操作,但是,我无法添加附件(更具体地说,是使用获得附件的REST上传文件)。我已经在网上进行了广泛的研究,但是到目前为止,我还无法在VB.NET中找到任何有效的示例。要实际上传数据,我使用System.Net.WebClient。以下VB.NET代码完成了重要工作:
Dim Client As New System.Net.WebClient
Dim postBytes As Byte() = System.Text.Encoding.ASCII.GetBytes(postString)
Client.UploadData(URL,\"POST\",postBytes)
我的URL的简化版本如下:     
\"../REST/1.0/ticket/\" + ticketNumber + \"/comment?user=\" + userName + \"&pass=\" + password
最后,我发布的内容一个示例是:
postString = \"content=Text: RT Test\" + vbLf + \"Action: Comment\" + vbLf + \"Attachment: examplefile.jpg\" + vbLf + \"attachment_1=\"
如您所见,postString转换为字节,然后上载到服务器。但是,我不知道应该在哪里或如何发布原始附件本身。我们专门使用该状态的服务文档来使用变量\“ attachment_1,\”,该变量已添加到postString变量中,但是我不确定下一步应该是什么。是否应将文件转换为字节并附加到postBytes变量?我尝试了类似的操作,但是收到一条错误消息,提示找不到examplefile.jpg的附件。 谢谢你的帮助!     

解决方法

我们无法使用Client.UploadData(...),必须将整个帖子转换为字节,从附件之前的POST字段开始,然后是附件本身,最后是POST字段的其余部分。
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,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,buffer.Length)

            Do While (bytesRead > 0)

                requestStream.Write(buffer,bytesRead)
                bytesRead = fileStream.Read(buffer,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,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