使用multipart / form-data(Confluence)在C#中上传附件

时间:2016-09-05 13:32:49

标签: c# post multipartform-data confluence-rest-api

我一直试图按照Confluence Documentation on posting an attachment在汇合页面上发布附件。 我尝试使用以下代码上传附件(.txt文件或任何图像文件)。我还使用了curl命令,它适用于本地安装的汇流,但是没有给出"证书缺失"在线上传时出错。 C#中的代码片段,我现在正在工作的是:

string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Credentials = CredentialCache.DefaultCredentials;
req.Headers.Add("X-Atlassian-Token", "nocheck");
req.Method = "POST";
req.ContentType = "multipart/form-data; boundary=" + boundary;
string contentDisp = "Content-Disposition: form-data; name=\"file\"; filename=\"foo.txt\"";
string contentType = "Content-Type: text/plain";
string fullContents = "{0}\r\n{1}\r\n{2}\r\n\r\n{3}\r\n{4}--", boundary, contentDisp,contentType, Encoding.Default.GetString(contents), boundary;
req.ContentLength = fullContents.Length;
using (StreamWriter reqStream = new StreamWriter(req.GetRequestStream()))
{
reqStream.Write(fullContents);
reqStream.Flush();
reqStream.Close();
}
var httpResponse = (HttpWebResponse)req.GetResponse(); 

我得到的错误是:"未处理的类型' System.Net.WebException'发生在System.dll中。附加信息:远程服务器返回错误:(400)错误请求。"

1 个答案:

答案 0 :(得分:-1)

希望这会有所帮助

我在VB中发布它以防万一有翻译问题。你可以在这里转换它:

CodeConverter

Dim nvc As New System.Collections.Specialized.NameValueCollection() 'NOTE: Nothing to send at this time but must be initialized and passed
Dim strTargetUri As String = "https://yourserver.com/rest/api/content/1234567890/child/attachment"
Dim attachmentItem As String = "C:\folder\yourfile.png"
AddImageAttachment(strTargetUri, attachmentItem, "file", "image/jpeg", nvc)

我将其分解为3个程序

Public Shared Sub AddImageAttachment(ByVal uri As String, ByVal filePath As Hub.AttachmentElement, ByVal fileParameterName As String, ByVal contentType As String, ByVal otherParameters As Specialized.NameValueCollection)

    ServicePointManager.ServerCertificateValidationCallback = Function(sender, certificate, chain, sslPolicyErrors) True

    Dim strFileName As String = filePath.SourceFileName
    Dim strPathAndFileName As String = filePath.SourcePathAndFileName

    Dim boundary As String = "---------------------------" & DateTime.Now.Ticks.ToString("x")
    Dim newLine As String = System.Environment.NewLine
    Dim boundaryBytes As Byte() = Text.Encoding.ASCII.GetBytes(newLine & "--" & boundary & newLine)
    Dim request As Net.HttpWebRequest = Net.WebRequest.Create(uri)
    'request.Proxy = New WebProxy("127.0.0.1", 8888)    'Proxy Entry for Tracing with Fiddler

    request.ContentType = "multipart/form-data; boundary=" & boundary
    request.Headers.Add("X-Atlassian-Token: no-check")
    request.Headers.Add("Authorization", "Basic " & Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(credLogonID & ":" & credPassword)))
    request.Method = "POST"
    request.Credentials = Net.CredentialCache.DefaultCredentials

    Try

        Using requestStream As Stream = request.GetRequestStream()
            Dim formDataTemplate As String = "Content-Disposition: form-data; name=""{0}""{1}{1}{2}"
            If otherParameters.Keys.Count > 0 Then
                For Each key As String In otherParameters.Keys
                    requestStream.Write(boundaryBytes, 0, boundaryBytes.Length)
                    Dim formItem As String = String.Format(formDataTemplate, key, newLine, otherParameters(key))
                    Dim formItemBytes As Byte() = Text.Encoding.UTF8.GetBytes(formItem)
                    requestStream.Write(formItemBytes, 0, formItemBytes.Length)
                Next key
            End If

            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length)

            Dim headerTemplate As String = "Content-Disposition: form-data; name=""{0}""; filename=""{1}""{2}Content-Type: {3}{2}{2}"
            Dim header As String = String.Format(headerTemplate, fileParameterName, strFileName, newLine, contentType)
            Dim headerBytes As Byte() = Text.Encoding.UTF8.GetBytes(header)
            requestStream.Write(headerBytes, 0, headerBytes.Length)

            Dim byteImage As Byte() = GetImage(strPathAndFileName)

            requestStream.Write(byteImage, 0, byteImage.Length)

            Dim trailer As Byte() = Text.Encoding.ASCII.GetBytes(newLine & "--" + boundary + "--" & newLine)
            requestStream.Write(trailer, 0, trailer.Length)
        End Using

        Dim response As WebResponse = Nothing

    Catch e As Net.WebException
        MsgBox(e.Message)
    End Try
End Sub

的getImage

Private Shared Function GetImage(ByVal URL As String) As Byte()

    GetImage = Nothing

    ServicePointManager.ServerCertificateValidationCallback = Function(sender, certificate, chain, sslPolicyErrors) True
    Dim Request As HttpWebRequest = Nothing
    Dim Response As HttpWebResponse = Nothing
    Try
        Request = WebRequest.Create(URL)
        'request.Proxy = New WebProxy("127.0.0.1", 8888)    'Proxy Entry for Tracing with Fiddler
        Request.Credentials = CredentialCache.DefaultCredentials
        Response = CType(Request.GetResponse, WebResponse)
        If Request.HaveResponse Then
            If Response.StatusCode = Net.HttpStatusCode.OK Then
                GetImage = convertStreamToByte(Response.GetResponseStream)
            End If
        End If
    Catch e As WebException
        MsgBox(e.Message)
    End Try

    Return GetImage

End Function

和字节转换器

Private Shared Function convertStreamToByte(ByRef incomingStream As Stream) As Byte()

    Dim result As Byte()
    Dim buffer As Byte() = New Byte(4095) {}
    Using memoryStream As New MemoryStream()
        Dim count As Integer = 0
        Do
            count = incomingStream.Read(buffer, 0, buffer.Length)
            memoryStream.Write(buffer, 0, count)
        Loop While count <> 0
        result = memoryStream.ToArray()
    End Using
    Return result

End Function

我会看看我是否能找到一些我曾经将这些链接结合在一起的链接