C# 内容处置头中的Unicode

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

我使用在HttpHandler child中实现的HttpContext对象来下载一个文件,当我的文件名中有非ascii字符时,它在IE中看起来很奇怪,而在Firefox中看起来很好

代码如下:-

       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
,这就像一个符咒(它没有添加“+”符号)。它不起作用。该框架已经很好地处理了编码。