c# - 使用 HttpClient 上传多部分表单文件

标签 c# dotnet-httpclient

我正在尝试使用此处记录的 Support Bee API 创建附件: https://supportbee.com/api#create_attachment

我编写了一个服务,它使用 HttpClient 创建并使用文件名发送请求。

如果我在 Postman 中测试,它会成功。我正在为正文使用 form-data 并从 UI 中选择要上传的文件:

enter image description here

当我尝试通过我的 HttpClient 服务上传它时,它不起作用:

public async Task<string> CreateAttachmentAsync(string fileName)
{
    // "client" is HttpClient provided via D.I.

    MultipartFormDataContent content = new MultipartFormDataContent();
    content.Add(new StreamContent(new FileStream(fileName, FileMode.Open)), "files[]");

    using (HttpResponseMessage response = await client.PostAsync(
        "https://xxx.supportbee.com/attachments?auth_token=xxx",
        content))
    {
        string responseString = await response.Content.ReadAsStringAsync();

        return responseString;
    }
}

这会导致 500 内部服务器错误。检查 MultipartFormDataContent 对象,我可以看到它的 header 值是自动设置的:

{ Content-Type: multipart/form-data; boundary="c9be3778-4de5-4460-9929-adcaa6bdda79" Content-Length: 164 }

我也曾尝试先将文件读入字节数组,然后使用 ByteArrayContent 而不是 StreamContent 但无济于事。响应没有提供任何帮助,但由于请求在 Postman 中有效,我的代码肯定有问题,但我不知道还能尝试什么。

编辑:我使用 Fiddler 进行测试,将成功的 Postman 请求与我的代码进行比较。这是 Postman 的请求:

POST https://xxx.supportbee.com/attachments?auth_token=xxx HTTP/1.1 User-Agent: PostmanRuntime/7.22.0 Accept: / Cache-Control: no-cache Postman-Token: f84d22fa-b4b1-4bf5-b183-916a786c6385 Host: xx.supportbee.com Content-Type: multipart/form-data; boundary=--------------------------714700821471353664787346 Accept-Encoding: gzip, deflate, br Content-Length: 241 Connection: close

----------------------------714700821471353664787346 Content-Disposition: form-data; name="files[]"; filename="sample.txt" Content-Type: text/plain

This contains example text. ----------------------------714700821471353664787346--

以及来 self 的代码的失败请求:

POST https://xxx.supportbee.com/attachments?auth_token=xxx HTTP/1.1 Host: xxx.supportbee.com Accept: / Accept-Encoding: gzip, deflate, br Connection: close Content-Type: multipart/form-data; boundary="ea97cbc1-70ea-4cc4-9801-09f5feffc763" Content-Length: 206

--ea97cbc1-70ea-4cc4-9801-09f5feffc763 Content-Disposition: form-data; name="files[]"; filename=sample; filename*=utf-8''sample

This contains example text. --ea97cbc1-70ea-4cc4-9801-09f5feffc763--

我能看到的区别是 Postman 中的各个部分都有自己的 Content-Type: text/plain 文件头,而我的没有。我无法添加这个,因为如果我尝试'不支持多个值。'

最佳答案

首先,重要的是要注意 500 响应类似于未处理的异常,也就是说,这是他们端的错误,或多或少不可能确定您做错了什么。我建议向他们报告,虽然我不熟悉 Support Bee,但我希望他们有很好的支持人员可以帮助您解决问题。 :)

但是如果您想玩猜谜游戏,我同意您成功的 Postman 调用和您的代码之间的细微差别是一个很好的起点。对于该 header ,请注意 contentMultipartFormDataContent。您实际上想在 StreamContent 对象上设置它。

另外,查看 Postman 发送的请求 header ,看看 Content-Disposition 是否包含 filename。如果 API 需要它,您可能还需要将它添加到您的代码中。

以下是如何做到这两点:

var fileContent = new StreamContent(File.OpenRead(path));
fileContent.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
content.Add(fileContent, "files[]", Path.GetFileName(path));

如果这不是问题所在,请查看 Postman 中请求正文的“原始”版本,以及那 11 个请求 header ,看看是否可以发现您可能遗漏的任何其他内容。

关于c# - 使用 HttpClient 上传多部分表单文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60176740/

相关文章:

c# - 如何在本地网络的一台计算机上运行业务逻辑,在另一台计算机上运行GUI?

c# - 从 MVC3 中的查询字符串中删除一个值并重定向到生成的 URL

.net-core - .Net Core HttpClient可以实现Http/2复用吗?

c# - 如何使用 HttpClient 从特定 IP 地址发送请求? C#

c# - Xamarin 表单 HTTPClient 调用崩溃

c# - 在 Windows Phone 8 中使用 HttpClient 执行 POST 时出现内部服务器错误

c# - .NET:由于字典,HttpClient 中的 CPU 使用率为 100%?

c# - 将节点添加到 treeView 中的特定父节点 (c#)

c# - 禁用测试网络作业

c# - 获取数组中最接近的值