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

时间:2020-02-11 20:18:44

标签: 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 Internal Server Error。检查MultipartFormDataContent对象,我可以看到它的标题值是自动设置的:

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

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

编辑:我与Fiddler进行了测试,以比较成功的Postman请求与我的代码。这是邮递员的要求:

开机自检 https://xxx.supportbee.com/attachments?auth_token=xxx HTTP / 1.1用户代理:PostmanRuntime / 7.22.0接受: / 缓存控制: 无缓存邮递员令牌:f84d22fa-b4b1-4bf5-b183-916a786c6385主机: xx.supportbee.com内容类型:multipart / form-data; 边界= -------------------------- 714700821471353664787346 接受编码:gzip,deflate,br内容长度:241连接: 关闭

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

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

以及我的代码中失败的请求:

开机自检 https://xxx.supportbee.com/attachments?auth_token=xxx HTTP / 1.1主机:xxx.supportbee.com接受: / 接受编码: gzip,deflate,br连接:close内容类型:multipart / form-data; boundary =“ ea97cbc1-70ea-4cc4-9801-09f5feffc763”“内容长度:206

-ea97cbc1-70ea-4cc4-9801-09f5feffc763内容处置:表格数据; name =“ files []”; filename = sample;文件名* = utf-8''样本

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

我可以看到的区别是Postman中的各个部分都有自己的文件Content-Type: text/plain标头,而我的则没有。我无法添加它,因为如果我尝试content.Headers.Add("Content-Type", "text/plain");,它将失败,并显示“无法添加值,因为标头'Content-Type'不支持多个值”。

1 个答案:

答案 0 :(得分:1)

首先,请务必注意,500响应类似于未处理的异常,即,这是错误,并且或多或少无法确定您做错了什么。我建议向他们报告,尽管我对Support Bee并不熟悉,但我希望他们有很好的支持人员可以帮助您解决问题。 :)

但是,如果您想玩猜谜游戏,我同意成功的Postman呼叫与代码之间的细微差别是一个不错的起点。对于该标头,请注意new_df <- new_df %>% group_by(id) %>% filter(n_distinct(year)==n()| row_number()==2) content。您实际上是想在MultipartFormDataContent对象上进行设置。

还要查看Postman发送的请求标头,看看StreamContent是否包含Content-Disposition。如果API期望的话,您可能还需要将其添加到代码中。

这两种方法都可以做到:

filename

如果这不是问题,请查看Postman中请求主体的“原始”版本以及这11个请求标头,看看是否可以发现可能缺少的其他内容。