C# 内容处置头中的Unicode
我使用在HttpHandler child中实现的HttpContext对象来下载一个文件,当我的文件名中有非ascii字符时,它在IE中看起来很奇怪,而在Firefox中看起来很好 代码如下:-C# 内容处置头中的Unicode,c#,.net,http-headers,content-disposition,C#,.net,Http Headers,Content Disposition,我使用在HttpHandler child中实现的HttpContext对象来下载一个文件,当我的文件名中有非ascii字符时,它在IE中看起来很奇怪,而在Firefox中看起来很好 代码如下:- context.Response.ContentType = ".cs"; context.Response.AppendHeader("Content-Length", data.Length.ToString()); context.Response.AppendHeader("Co
context.Response.ContentType = ".cs";
context.Response.AppendHeader("Content-Length", data.Length.ToString());
context.Response.AppendHeader("Content-Disposition", String.Format("attachment; filename={0}",filename));
context.Response.OutputStream.Write(data, 0, data.Length);
context.Response.Flush();
当我在文件名字段中提供“ޤŸ”时,它看起来与我在文件名中的不同,在firefox中看起来很好。添加EncodingType和字符集没有用
在ie中,它是“øƒƒ)ƒƒƜƒƒƜƒ¸”ÃƜƒƜƒƜƜƜƜƜƜƜƜƜƜƜƜƜƜ)Ɯ)ƜƜ)ƜƜƜƜ))ƜƜ
知道如何解决这个问题吗?我也有类似的问题。您必须使用或对文件名进行编码。我还记得firefox不需要它。此外,当文件名被url编码时,它破坏了文件名。我的代码:
// IE needs url encoding, FF doesn't support it, Google Chrome doesn't care
if (Request.Browser.IsBrowser ("IE"))
{
fileName = Server.UrlEncode(fileName);
}
Response.Clear ();
Response.AddHeader ("content-disposition", String.Format ("attachment;filename=\"{0}\"", fileName));
Response.AddHeader ("Content-Length", data.Length.ToString (CultureInfo.InvariantCulture));
Response.ContentType = mimeType;
Response.BinaryWrite(data);
编辑
我更仔细地阅读了说明书。首先,各国指出:
当前[RFC 2045]语法将参数值(以及内容处置文件名)限制为US-ASCII
但后来我发现[RFC 2045]是绝对删除的,必须引用,其中指出:
重复使用星号(“*”)以提供
语言和语言的指标
存在字符集信息
并且正在使用编码。单人间
引号(“”)用于分隔
字符集与语言信息
在参数的开头
价值百分比符号(“%”)用作
编码标志,它与
RFC 2047
这意味着您可以对非ascii符号使用UrlEncode,只要您包括中所述的编码。以下是一个例子:
string.Format("attachment; filename=\"{0}\"; filename*=UTF-8''{0}", Server.UrlEncode(fileName, Encoding.UTF8));
请注意,
filename
是在filename*
的基础上添加的,以实现向后兼容性。您也可以选择另一种编码并相应地修改参数,但UTF-8涵盖了所有内容。您可能需要阅读并查看上的测试。HttpUtility.UrlPathEncode可能是更好的选择。因为URLEncode将用“+”符号替换空格。对于我来说,此解决方案适用于所有主要浏览器:
Response.AppendHeader("Content-Disposition", string.Format("attachment; filename*=UTF-8''{0}", HttpUtility.UrlPathEncode(fileName).Replace(",", "%2C"));
var mime = MimeMapping.GetMimeMapping(fileName);
return File(fileName, mime);
使用ASP.NETMVC3
替换是必要的,因为Chrome不喜欢参数值中的逗号(,):对我来说,这解决了问题:
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(data)
};
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileNameStar = "foo-ä-€.html"
};
当我在fiddler中查看repsonse时,我可以看到文件名已自动使用UTF-8编码:
如果我们查看contentdispositionheader的值,我们可以看到它与@johannesgeyer的答案相同。唯一的区别是我们不必自己进行编码,ContentDispositionHeaderValue类会处理这个问题
正如Julian Reschke提到的,我在上使用了内容处置头的Testcases。
有关ContentDispositionHeaderValue类的信息可在MSDN上找到。对于Asp.Net Core(本帖第2版),UrlPathEncode已被弃用,以下是如何实现所需结果:
System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
{
FileName = Uri.EscapeUriString(fileName),
Inline = true // false = prompt the user for downloading; true = browser to try to show the file inline
};
Response.Headers.Add("Content-Disposition", cd.ToString());
我使用
Uri.EscapeUriString
将所有字符转换为十六进制表示,使用string.Normalize
将Unicode规范化表单C转换为字符串。
(在ASP.NET MVC5 framework 4.5中测试)
var contentDispositionHeader=new System.Net.Mime.ContentDisposition
{
Inline=false,
FileName=Uri.EscapeUriString(Path.GetFileName(pathFile)).Normalize()
};
Add(“contentdisposition”,contentDispositionHeader.ToString());
字符串mimeType=MimeMapping.GetMimeMapping(Server.MapPath(pathFile));
返回文件(文件,mimeType);
这是文件的内容还是文件名本身?@leppie,这是文件名itself@Sergej,我尝试了你所说的,效果很好,你能解释一下为什么它破坏了文件名吗,这样在我真正实现它之前我就清楚了。根据Ash的回答,我使用了这个,但是使用了urlpathcode
,这就像一个符咒(它没有添加“+”符号)。它不起作用。该框架已经很好地处理了编码。