Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# HttpClient在内容处理中编码错误_C#_Http_Content Disposition - Fatal编程技术网

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);
}