简体   繁体   English

如何使用MultipartFormDataContent为HttpClient请求设置Content-Type标头?

[英]How do you set the Content-Type header for an HttpClient request with MultipartFormDataContent?

I looked at the MS Source code according to their interpretation the HttpClient itself does not have "Content-Type" only the content should have content-type. 我根据他们的解释看了看MS源代码,HttpClient本身没有“ Content-Type”,只有内容应该具有content-type。 Seems logical except when you're dealing with MultipartFormDataContent. 似乎合乎逻辑,除非您要处理MultipartFormDataContent。 MultipartFormDataContent completely ignores the following code: MultipartFormDataContent完全忽略以下代码:

string boundary = "--" + GenerateRandomString();
using (var content = new MultipartFormDataContent(boundary))
{
    content.Headers.ContentType = new MediaTypeHeaderValue($"multipart/form-data");
    content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("boundry", boundary));
    ...
}

No "Content-Type" is present in the request. 请求中没有“ Content-Type”。 And also ignores: 并且也忽略:

string boundary = "--" + GenerateRandomString();
using (var content = new MultipartFormDataContent(boundary))
{
    content.Headers.Remove("Content-Type");
    content.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=" + boundary);
    ...
}    

Attemting to set it at on the HttpClient 尝试将其设置在HttpClient上

client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=" + boundary);

throws the following error: 引发以下错误:

System.InvalidOperationException: 'Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects.'

I can find plenty of examples of how to do this using StringContent but none with MultipartFormDataContent. 我可以找到很多使用StringContent进行此操作的示例,但没有使用MultipartFormDataContent进行此操作的示例。 MultipartFormDataContent allows setting the Content-Type and Content-Disposition with each field, I need this more at the client level. MultipartFormDataContent允许使用每个字段设置Content-Type和Content-Disposition,我在客户端级别需要更多。 I need a header that looks something like this: 我需要一个看起来像这样的标题:

accept: application/json
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Authorization: Basic ZXlKbGRDSTZJakUxTWpZNU9UTXpOTnpkMjl5WkNJNklqa3haRGxtWkdKa1lUazRaVEJqWmpsalpUaGxNV1V3TXpOalxuWmpCbE1tVXhJaXdpZFhObGNpSTZJbUZrYldsdUluMD1cbjo=
Cache-Control: no-cache

Many non-Microsoft APIs require the "boundary" tag so it can distinguish the individual fields of data being sent. 许多非Microsoft API需要使用“边界”标记,因此它可以区分要发送的数据的各个字段。 The validation here on the request seems a little over the top. 请求上的验证似乎有点过头了。 Even TryAddWithoutValidation doesn't work (maybe a bug?). 甚至TryAddWithoutValidation都不起作用(也许是错误?)。 I realize that it may be possible to interpret RFC7578 in a way that says it shouldn't be required but flat out not allowing it doesn't seem right to me either. 我意识到,可以以一种不应该要求的方式解释RFC7578,但是完全不允许这样做对我来说也不对。 Anyone else ever run into this issue and solve it. 任何其他人都遇到过这个问题并解决了。

Initially I thought this was an HttpClient bug. 最初,我认为这是HttpClient错误。 I added logging to capture the request and the response. 我添加了日志记录以捕获请求和响应。 That logging was missing headers which lead me to believe that the missing "multi-part/form-data" content header was the issue and the reason the API I'm using kept telling me it couldn't find a required field. 该日志记录缺少标题,这使我相信缺少的“多部分/表单数据”内容标题是问题所在,而我使用的API的原因一直告诉我找不到所需字段。 It turns out to be an issue with how the API handles the data it's sent when it's multi-part/form-data. 事实证明,当它是多部分/表单数据时,API如何处理它发送的数据。 After comparing both my HttpWebRequest and the HttpClient request in fiddler I discovered the following difference in the data being sent: 在Fiddler中比较了HttpWebRequest和HttpClient请求后,我发现正在发送的数据存在以下差异:

HttpWebRequest HttpWebRequest的

----vekhftkcthxr
Content-Disposition: form-data; name="name";

d30-20180524

HttpClient HttpClient的

----bcgifxyjkmkw
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=name

d30-20180524

I build the HttpWebRequest manually so I included the quotes and ending semi-colons. 我手动构建HttpWebRequest,所以我包括了引号和结尾的分号。 The HttpClient request is built for me and does not include the extra quotes and semi-colon. HttpClient请求是为我构建的,不包括多余的引号和分号。 So the API I am using does not play well with request being generated by the HttpClient even though the request is technically correct. 因此,即使请求在技术上是正确的,我正在使用的API也无法很好地与HttpClient生成的请求配合使用。

Thanks to Panagiotis Kanavos for showing me my error. 感谢Panagiotis Kanavos向我展示了我的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM