我有一个名为AttachmentDownload.aspx的文件,里面的Page_Load方法有这样的代码提供下载文件。所有名称在IE中都能正常工作,但名称中包含“;”要么 ”#”。它们为用户提供了名为“AttachmentDownload.aspx”的文件保存。这有解决方法吗?
以下是一个例子:
var fileName = Server.UrlPathEncode (";%.txt");
Response.AddHeader("content-disposition", String.Format("attachment;filename=\"{0}\"", fileName));
Response.WriteFile(path);
Response.End();
答案 0 :(得分:8)
所有名称在IE中都能正常工作,但名称中包含“;”或“#”。
我不能用'#'重现问题但是';'肯定会打破它。就像'''和'\'一样(你可以在Unix上的文件名中使用它,这将破坏你的引用字符串)。
在RFC1521中定义了在RFC822系列参数化标头中包含带外字符的“正确”解决方案,如RFC2822:不应包含在“令牌”中的字符串应该被包装在带引号的字符串中,RFC2231定义为“和\字符反斜杠转义,然后用引号括起来。
然后http://www.example.com/AttachmentDownload.aspx/Foo%23Bar以一种非常复杂的方式扩展它,在头参数中包含非ASCII字符,理论上你可以使用它来支持Unicode字符。
实际上:HTTP实际上并不是RFC822系列规范,并且这些东西都不适用于常规浏览器(除了Opera中的反斜杠转义)。没有可靠的方法来获取客户端的Unicode Content-Disposition文件名,而你的';'问题不是因为任何转义问题,而是因为IE无法解析太妃糖的参数化标题(它分裂了字符串中的下一个分号,即使它被引号括起来。)
对于可靠的跨浏览器文件名设置,您可以在现实世界中采用两种方法:
在将文件名放入Content-Disposition标头之前,从文件名中删除任何令人反感的内容。这包括前导/尾随空格/点,大多数其他标点符号和任何非ASCII。
根本不要在Content-Disposition标头中指定文件名,让浏览器在URL的最后部分计算出要使用的文件名。要阻止它选择“AttachmentDownload.aspx”,您可以将任何您喜欢的内容作为尾随URL部分,例如:
{{3}}
这要求您使用普通URL编码和UTF-8的Unicode字符编码大多数标点符号,但至少可以获取字符。上面的结果是'Foo; Bar'的文件下载提示。
请注意,即使您可以对像这样的URL路径部分中的“不喜欢”的Windows不友好的字符进行编码,对于下载的文件,最好不要这样做,因为IE会通过尝试保存来响应该文件在文件名中使用'\ n'',并且会无声地神秘地响应。
答案 1 :(得分:3)
我开始只清理所有特殊字符的文件名。我想出了一个映射表,它应该映射大多数常用的字符。
//http://www.pjb.com.au/comp/diacritics.html
private static string[,] CharacterReplacements = {
{ " ", "-"},
{ "&", "-"},
{ "?", "-"},
{ "!", "-"},
{ "%", "-"},
{ "+", "-"},
{ "#", "-"},
{ ":", "-"},
{ ";", "-"},
{ ".", "-"},
{ "¢", "c" }, //cent
{ "£", "P" }, //Pound
{ "€", "E" }, //Euro
{ "¥", "Y" }, //Yen
{ "°", "d" }, //degree
{ "¼", "1-4" }, //fraction one-quarter
{ "½", "1-2" }, //fraction half
{ "¾", "1-3" }, //fraction three-quarters}
{ "@", "AT)"}, //at
{ "Œ", "OE" }, //OE ligature, French (in ISO-8859-15)
{ "œ", "oe" }, //OE ligature, French (in ISO-8859-15)
{"Å","A" }, //ring
{"Æ","AE"}, //diphthong
{"Ç","C" }, //cedilla
{"È","E" }, //grave accent
{"É","E" }, //acute accent
{"Ê","E" }, //circumflex accent
{"Ë","E" }, //umlaut mark
{"Ì","I" }, //grave accent
{"Í","I" }, //acute accent
{"Î","I" }, //circumflex accent
{"Ï","I" }, //umlaut mark
{"Ð","Eth"}, //Icelandic
{"Ñ","N" }, //tilde
{"Ò","O" }, //grave accent
{"Ó","O" }, //acute accent
{"Ô","O" }, //circumflex accent
{"Õ","O" }, //tilde
{"Ö","O" }, //umlaut mark
{"Ø","O" }, //slash
{"Ù","U" }, //grave accent
{"Ú","U" }, //acute accent
{"Û","U" }, //circumflex accent
{"Ü","U" }, //umlaut mark
{"Ý","Y" }, //acute accent
{"Þ","eth"}, //Icelandic - http://en.wikipedia.org/wiki/Thorn_(letter)
{"ß","ss"}, //German
{"à","a" }, //grave accent
{"á","a" }, //acute accent
{"â","a" }, //circumflex accent
{"ã","a" }, //tilde
{"ä","ae"}, //umlaut mark
{"å","a" }, //ring
{"æ","ae"}, //diphthong
{"ç","c" }, //cedilla
{"è","e" }, //grave accent
{"é","e" }, //acute accent
{"ê","e" }, //circumflex accent
{"ë","e" }, //umlaut mark
{"ì","i" }, //grave accent
{"í","i" }, //acute accent
{"î","i" }, //circumflex accent
{"ï","i" }, //umlaut mark
{"ð","eth"}, //Icelandic
{"ñ","n" }, //tilde
{"ò","o" }, //grave accent
{"ó","o" }, //acute accent
{"ô","o" }, //circumflex accent
{"õ","o" }, //tilde
{"ö","oe"}, //umlaut mark
{"ø","o" }, //slash
{"ù","u" }, //grave accent
{"ú","u" }, //acute accent
{"û","u" }, //circumflex accent
{"ü","ue"}, //umlaut mark
{"ý","y" }, //acute accent
{"þ","eth"}, //Icelandic - http://en.wikipedia.org/wiki/Thorn_(letter)
{"ÿ","y" }, //umlaut mark
};
或者你可以在这里获得整个代码:
http://remy.supertext.ch/2012/08/clean-filenames/
如果您发现遗失的字符,请告诉我。
答案 2 :(得分:2)
某些浏览器不支持带有特殊符号的文件名(例如:space;#@!$)或非Unicode字符,或者导致客户端计算机中的文件名不正确。 这是一篇名为chanext的中文文章,他给出了解决这个问题的完美方法: 本文给出了一个示例代码(用c#编写),以展示如何在所有四种流行的浏览器(IE; Opera; Firefox和Chrome)中获得完美的解决方案 文件名“Microsoft.Asp.Net.doc”和“F ile ;;!@%#^& y.doc”都可以使用作者在本文中提供的方式正确输出。
http://ciznx.com/post/aspnetstreamdownloaddisplaynonunicodespacechar.aspx
答案 3 :(得分:0)
UrlPathEncode仅对类似URL的字符串的“路径”部分进行编码,请尝试使用 Server.UrlEncode或HttpUtility.UrlEncode。