C# HttpClient在内容处理中编码错误
我正在用C# HttpClient在内容处理中编码错误,c#,http,content-disposition,C#,Http,Content Disposition,我正在用HttpClient发布一个图像,它对使用拉丁名称的文件很有效,但一旦名称包含任何非ASCII字符,它就会转换为一系列问号。如果我创建一个html表单并使用浏览器发布文件,文件名将以UTF8格式发送,目标服务器完全接受它 using (var client = new HttpClient()) { var streamContent = new StreamContent(someImageFileStream); streamContent.Headers.Add(
HttpClient
发布一个图像,它对使用拉丁名称的文件很有效,但一旦名称包含任何非ASCII字符,它就会转换为一系列问号。如果我创建一个html表单并使用浏览器发布文件,文件名将以UTF8格式发送,目标服务器完全接受它
using (var client = new HttpClient())
{
var streamContent = new StreamContent(someImageFileStream);
streamContent.Headers.Add(
"Content-Disposition",
"form-data; name=\"image\"; filename=\"Тест.jpg\"");
var content = new MultipartFormDataContent();
content.Add(streamContent);
await client.PostAsync("http://localhost.fiddler/", content);
}
这将产生以下请求:
POST http://localhost/ HTTP/1.1
Content-Type: multipart/form-data; boundary="e6fe89be-e652-4fe3-8859-8c7a339c5550"
Host: localhost
Content-Length: 10556
--e6fe89be-e652-4fe3-8859-8c7a339c5550
Content-Disposition: form-data; name="image"; filename="????.jpg"
...here goes the contents of the file...
我知道HttpClient
可能根据某些标准工作,但无论如何,有什么解决方法吗
更新:外部API不希望接受
filename*=utf-8''СССС.jpg
格式,它希望filename=“ССС.jpg”
而不是添加您自己构建的头,请使用.NET库:
streamContent.Headers.ContentDisposition =
new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data") {
Name = "image",
FileName = "Тест.jpg" };
这将根据和创建标头
好的,我找到了一种方法,可以强制
MultipartFormDataContent
忘记古老的rfc,而改用UTF8。诀窍是使用反射覆盖内部静态类HttpRuleParser
中定义的DefaultHttpEncoding
typeof(HttpClient)
.Assembly
.GetType("System.Net.Http.HttpRuleParser")
.GetField("DefaultHttpEncoding", BindingFlags.Static | BindingFlags.NonPublic)
.SetValue(null, System.Text.Encoding.UTF8);
不确定可能会导致哪些不良后果,但我认为没有。这是另一种在不篡改内部字段的情况下绕过HttpClient限制的方法。灵感来自
我确认,即使是.net core 2.2也不支持上载名称包含非ASCII字符的文件。HttpClient确实根据某些标准工作,但Java服务器不关心该标准,并且希望使用UTF-8格式的头。如果有帮助,您还可以删除“文件名*”
不幸的是,我发布到的API不接受这种格式。
filename*=
(或者更确切地说,*=
)是一种正确但几乎不受支持的编码非US-ASCII值的方法。请检查。你解决了吗?@Shirandor请看下面我的答案。在使用RestClient和HttpClient时遇到了同样的问题,除了篡改内部字段之外,没有其他方法吗?“即使是.net core 2.2也没有适当的支持”MultipartFormDataContent\StreamContent似乎在规范(RFC)afaics下100%工作。问题是似乎没有其他人这样做,即使是微软的老东西,比如HttpRequest\HttpPostedFile。我认为微软应该在这一点上给IETF指手画脚,仅仅将文件名编码为普通的utf8。
typeof(HttpClient)
.Assembly
.GetType("System.Net.Http.HttpRuleParser")
.GetField("DefaultHttpEncoding", BindingFlags.Static | BindingFlags.NonPublic)
.SetValue(null, System.Text.Encoding.UTF8);
using (var client = new HttpClient())
{
var streamContent = new StreamContent(someImageFileStream);
streamContent.Headers.Add("Content-Disposition",
new string(Encoding.UTF8.GetBytes("form-data; name=\"image\"; filename=\"Тест.jpg\"").
Select(b => (char)b).ToArray()));
var content = new MultipartFormDataContent();
content.Add(streamContent);
await client.PostAsync("http://localhost.fiddler/", content);
}
//It deletes filename* parametr
foreach (var content in multipartContent) {
var headerContent = content.Headers.ContentDisposition.Parameters.Where(x => x.Name == "filename*").SingleOrDefault();
if(headerContent != null)
content.Headers.ContentDisposition.Parameters.Remove(headerContent);
}