我创建了一个用于下载文件的函数,除了文件名之外,它可以正常工作。当我下载带有泰语名称的文件时,其名称变成了HTML实体。
例如:
- 原始文件名:
ไฟล์_1_ข้อมูลลูกค้า__Customer_Information_.xml
- 保存文件名:
"ไฟล์_1_ข้อมูลลูกค้า__Customer_Information_.xml".
如何用原始名称保存文件?这是我的代码:
[HttpGet]
public async Task<IActionResult> DownloadOtherFile(string id, string filename)
{
string trueFileName = HttpUtility.HtmlDecode(filename);
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", filename);
HttpClient client = new HttpClient
{
BaseAddress = new Uri(option.ApiBaseUrl)
};
try
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", HttpContext.Session.GetString("token"));
HttpResponseMessage response = await client.GetAsync("/file/other/job/" + id + "/" + trueFileName);
var content = await response.Content.ReadAsStreamAsync();
return File(content, "APPLICATION/octet-stream", trueFileName);
}
catch (Exception)
{
//error
}
finally
{
client.Dispose();
}
return null;
}
长话短说,标题值仅接受ISO-8859-1字符,因此始终编码非ASCII字符。客户应该能够识别编码。如果不是,这是客户的问题。asp.net core die 遵循源代码显示的标准。
内容类型标头不接受文件名。该文件名在内容插入标题中指定。
用特定名称返回文件的正确方法是使用文件(流,字符串,字符串(方法或将文件名作为Content-Disposition
标头的一部分传递。
您应该替换:
return File(content, "APPLICATION/octet-stream, trueFileName");
with:
return File(content, "application/octet-stream", trueFileName);
update
我不能再现任何问题。我创建了一个新的ASP.NET Core MVC应用程序,其Home/Index
方法仅为:
public IActionResult Index()
{
var trueFileName = "ไฟล์_1_ข้อมูลลูกค้า__Customer_Information_.xml";
var bytes=Encoding.UTF8.GetBytes("Hello");
return File(bytes, "APPLICATION/octet-stream", trueFileName);
}
浏览该URL下载了一个名称为
的文件ไฟล์_1_ข้อมูลลูกค้า__Customer_Information_.xml
我用铬,Firefox和Edge Chromium对此进行了测试。
该名称未编码HTML,它是按照应有的方式编码的。原始的HTTP响应是:
HTTP/1.1 200 OK
Date: Tue, 06 Aug 2019 15:13:54 GMT
Content-Type: APPLICATION/octet-stream
Server: Kestrel
Content-Length: 5
Content-Disposition: attachment; filename=_____1_______________Customer_Information_.xml; filename*=UTF-8''%E0%B9%84%E0%B8%9F%E0%B8%A5%E0%B9%8C_1_%E0%B8%82%E0%B9%89%E0%B8%AD%E0%B8%A1%E0%B8%B9%E0%B8%A5%E0%B8%A5%E0%B8%B9%E0%B8%81%E0%B8%84%E0%B9%89%E0%B8%B2__Customer_Information_.xml
Hello
更新2
该文件名作为URL参数从客户端传递,并且可能编码两次。这是HtmlDecode
产生另一个HTML编码字符串的唯一方法。
此通话:
var fileName="ไฟล์_1_ข้อมูลลูกค้า__Customer_Information_.xml";
var actualName=HttpUtility.HtmlDecode(fileName);
返回:
ไฟล์_1_ข้อมูลลูกค้า__Customer_Information_.xml
我怀疑该字符串被编码两次。
解决此类问题的问题是快速的第一步是使用Fiddler之类的调试代理来捕获和检查HTTP请求和响应。这不需要在服务器或客户端上进行任何更改。
类似的工具是所有现代浏览器的开发人员工具中的Network
选项卡。
另一个选项是更改Web应用程序的记录配置以记录请求和响应。这只能在测试或调查问题期间完成,因为它会产生文本的 lot 并减慢应用程序