使用多部分/表单数据在C#中上载附件(合流)

使用多部分/表单数据在C#中上载附件(合流),c#,post,multipartform-data,confluence-rest-api,C#,Post,Multipartform Data,Confluence Rest Api,我一直试图通过以下方式在汇流页面上发布附件。 我尝试了以下代码来上传附件(.txt文件或任何图像文件)。我还使用了curl命令,它适用于本地安装的confluence,但在线上传时出现了“Certificates missing”错误。 我目前正在处理的C#中的代码片段是: string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x"); HttpWebRequest req = (HttpWebRe

我一直试图通过以下方式在汇流页面上发布附件。 我尝试了以下代码来上传附件(.txt文件或任何图像文件)。我还使用了curl命令,它适用于本地安装的confluence,但在线上传时出现了“Certificates missing”错误。 我目前正在处理的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.dll中发生了类型为'System.Net.WebException'的未处理异常。其他信息:远程服务器返回了一个错误:(400)错误请求。”

希望这会有所帮助

我在VB中发布它,以防出现翻译问题。您可以在此处进行转换:

我把它分解成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
获取图像

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
私有共享函数convertStreamToByte(ByRef incomingStream作为流)作为字节()
将结果设置为字节()
作为字节()的Dim缓冲区=新字节(4095){}
将memoryStream用作新的memoryStream()
Dim计数为整数=0
做
count=incomingStream.Read(buffer,0,buffer.Length)
memoryStream.Write(缓冲区、0、计数)
在计数为0时循环
结果=memoryStream.ToArray()
终端使用
返回结果
端函数

我会看看我是否能找到一些我用来把这些联系在一起的链接

请阅读并提供实际错误,并说明您对该错误的研究结果。嘿@CodeCaster,感谢您让我意识到问题没有正确发布。我会编辑它,使它更有用。谢谢。Stack Overflow不是一个“分享你最喜欢的代码片段到DoX”的网站。这段拼凑起来的代码(例如)引入了OP的问题,但并没有回答OP的问题,即“为什么这段代码不工作?”,后者首先是无法回答的,因为从这个问题来看,它缺少它为什么不工作的确切原因。因此,虽然我为你帮助OP的努力鼓掌,但事实上,我担心你本身并没有帮助。我自己也经历过同样的问题,并了解到现有的知识并不能解决问题的全部范围。我相信维尼也在这一点上。我想让他和其他任何经历过这个问题的人知道答案需要几个步骤。再说一次,因为我自己也去过,所以这不是唯一的,更不用说作为多部分/表单数据请求的一部分上传文件的最干净的方式了。例如,见。如果你想教OP和后来的访问者一些东西,那么你应该记录下这段代码的实际功能和它所做的假设,而不是将代码当作“使用它,它会解决你的问题”。我希望我有时间,享受你的假期Hey@mreinsmith谢谢!!你的代码工作得很好!虽然我做了一些修改:在GetImage中,我使用System.Net.FileWebRequest代替了HttpWebRequest,并使用System.Net.WebResponse代替HttpWebResponse。休息一下,一切正常。非常感谢您的帮助。:)
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