[英]httpclient - how to set Content-Disposition to “application/json;” in a multipart
[英]HttpClient wrong encoding in Content-Disposition
我正在使用HttpClient
POST 圖像,它適用於具有拉丁名稱的文件,但只要名稱包含任何非 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"
。
好的,我找到了一種方法來強制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 限制的另一種方法。 受到這個答案的啟發。
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);
}
我確認即使 .net core 2.2 也不支持上傳名稱包含非 ASCII 字符的文件。 HttpClient 確實根據一些標准工作,但 Java 服務器不關心該標准並期望 UTF-8 格式的標頭。
如果有幫助,您還可以刪除“文件名*”
//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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.