C# 使用HttpClient上载多部分表单文件

C# 使用HttpClient上载多部分表单文件,c#,dotnet-httpclient,C#,Dotnet Httpclient,我正在尝试使用Support Bee API创建附件,如下所述: 我编写了一个服务,它使用HttpClient创建并发送使用文件名的请求 如果我在《邮递员》中测试,它会成功。我正在为正文使用表单数据,只是从UI中选择要上载的文件: 当我试图通过我的HttpClient服务上传它时,它不起作用: public async Task<string> CreateAttachmentAsync(string fileName) { // "client" is HttpClie

我正在尝试使用Support Bee API创建附件,如下所述:

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

如果我在《邮递员》中测试,它会成功。我正在为正文使用
表单数据
,只是从UI中选择要上载的文件:

当我试图通过我的
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;
    }
}
公共异步任务CreateAttachmentAsync(字符串文件名)
{
//“客户机”是通过D.I.提供的HttpClient。
MultipartFormDataContent内容=新的MultipartFormDataContent();
添加(新的StreamContent(新的文件流(fileName,FileMode.Open)),“files[]”;
使用(HttpResponseMessage response=wait client.PostAsync(
"https://xxx.supportbee.com/attachments?auth_token=xxx",
(内容)
{
string responseString=wait response.Content.ReadAsStringAsync();
回报率;
}
}
这将导致500内部服务器错误。检查
MultipartFormDataContent
对象时,我可以看到它的标题值正在自动设置:

{ 内容类型:多部分/表单数据;边界=“c9be3778-4de5-4460-9929-ADCAA6BDA79” 内容长度:164 }

我还尝试先将文件读取到字节数组,然后使用
ByteArrayContent
而不是
StreamContent
,但没有成功。响应没有提供任何帮助,但由于请求在Postman中工作,我的代码肯定有问题,但我不知道还可以尝试什么

编辑:我用Fiddler测试了成功的邮递员请求和我的代码。以下是邮递员的请求:

职位 HTTP/1.1用户代理:PostmanRuntime/7.22.0接受:/Cache控件: 无缓存邮差令牌:f84d22fa-b4b1-4bf5-b183-916a786c6385主机: xx.supportbee.com内容类型:多部分/表单数据; 边界=------------------------------------714700821471353664787346 接受编码:gzip,deflate,br内容长度:241连接: 接近

----------------------------714700821471353664787346内容处理:表单数据;name=“files[]”;filename=“sample.txt” 内容类型:文本/纯文本

这包含示例文本。 ----------------------------714700821471353664787346--

以及来自我的代码的失败请求:

职位 HTTP/1.1主机:xxx.supportbee.com接受:/Accept编码: gzip,deflate,br连接:关闭内容类型:多部分/表单数据; boundary=“ea97cbc1-70ea-4cc4-9801-09f5feffc763”内容长度:206

--ea97cbc1-70ea-4cc4-9801-09f5feffc763内容处理:表单数据;name=“files[]”;文件名=样本;文件名*=utf-8“示例

这包含示例文本。 --ea97cbc1-70ea-4cc4-9801-09f5feffc763--


我可以看到的区别是,Postman中的单个部分有自己的
内容类型:text/plain
文件头,而我的部分没有。我无法添加它,因为如果我尝试
content.Headers.add(“content-Type”,“text/plain”)由于“无法添加值,因为标题“内容类型”不支持多个值”而失败。

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

但是如果你想玩猜谜游戏,我同意成功的邮递员呼叫和代码之间的细微差别是一个很好的起点。对于该标题,请注意
content
MultipartFormDataContent
。实际上,您需要在
StreamContent
对象上设置它

另外,查看邮递员正在发送的请求标题,查看
内容处置
是否包含
文件名
。如果API需要,您可能也需要将其添加到代码中

以下是如何做到这两个方面:

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

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

此代码
使用(var response=wait client.SendAsync(message))
生成
GET
请求,您需要
POST
。首先,删除该行。您的
HttpClient
可能在发送前检查了
BaseAddress
。向我们展示
responseString
@RomanMarusyk的价值当我编辑我留下的问题时,有一些不好的残留代码,我错过了,现在已经删除了。它正在使用
PostAsync
发送将发布的请求。
responseString
只是包含“很抱歉,出现了一些问题(500)”的HTML。好的,尝试捕获来自邮递员和应用程序的请求并进行比较()。你的代码看起来不错。@RomanMarusyk我实际上就是这么做的。添加到我的帖子。这是否回答了你的问题?直接在
StreamContent
对象上设置
ContentType
标题使其工作。