这是一个神奇的问题,五年之内无人解决 asp.net下载文件时点击打开,中文文件名是url编码过的,求教!

fei07100107 2011-10-08 06:12:06
http://zhidao.baidu.com/question/130305726.html 百度知道
http://topic.csdn.net/t/20051104/11/4371322.html CSDN1次
http://topic.csdn.net/t/20040720/09/3190795.html CSDN2次
http://topic.csdn.net/t/20061027/09/5112791.html CSDN3次
http://topic.csdn.net/t/20061212/08/5223592.html CSDN4次
http://topic.csdn.net/u/20090302/16/276a0559-f05b-417a-9962-bac34efc23e4.html CSDN5次
.......
.......
.......
搜遍百度 google前几页,有点茫然了,问题跨度之久,回答人数之多,一次次的点击带来的一次次无果而终

其实这些都不是最重要的,最重要的是怎么这种问题让我碰到了,搜索几天,测试N久,两泪直流。

难道是我的方法错了吗?难道这个问题错了吗?

最后饱含深情的再次裸求一次,这个问题该怎么解决呢?

真切的期待着答案
...全文
1413 55 打赏 收藏 转发到动态 举报
写回复
用AI写文章
55 条回复
切换为时间正序
请发表友善的回复…
发表回复
carol88125 2012-09-21
  • 打赏
  • 举报
回复

string ext= Path.GetExtension(path);
Response.HeaderEncoding = System.Text.Encoding.GetEncoding("GBK");
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Length", file.FileSize.ToString());
Response.AddHeader("Content-Disposition", "attachment;filename=中文.txt");

设置一下HTTP头的编码格式,Content-Disposition时不使用URL编码
俗人1979 2011-12-15
  • 打赏
  • 举报
回复
也遇到了,还是没有解决,世界性难题啊
archu 2011-10-13
  • 打赏
  • 举报
回复
[Quote=引用 52 楼 smzen 的回复:]

楼主解决了吗?我也遇到了这个问题。
[/Quote]
http://blogs.msdn.com/b/asiatech_zh-cn/archive/2011/10/12/ie.aspx
smzen 2011-10-13
  • 打赏
  • 举报
回复
楼主解决了吗?我也遇到了这个问题。
smntbk 2011-10-11
  • 打赏
  • 举报
回复
楼主试试这个?

Response.AppendHeader("Content-Disposition", "attachment;filename=" + Server.UrlPathEncode(DownloadFile.Name));
地菜 2011-10-11
  • 打赏
  • 举报
回复
http://blog.ciznx.com/post/aspnetstreamdownloaddisplaynonunicodespacechar.aspx

这个看看,已经解决了,
经过实际应用, 没有出现bug
txyandwc 2011-10-11
  • 打赏
  • 举报
回复
mark
LIUMRZY 2011-10-11
  • 打赏
  • 举报
回复
后台用流生成文件,再生成个链接给前台下载!
onetwofree 2011-10-11
  • 打赏
  • 举报
回复
总的就是浏览器有关的,ie8下可以的,ff下不行。

ie8下可以的,ie6下有问题。

关键就是在输出Content-Disposition","attachment; filename
的时候,根据不同的客户端浏览器进行判断,有些需要编码输出,有时候不需要任何编码输出

fei07100107 2011-10-10
  • 打赏
  • 举报
回复
问题补充:
这里所说的不能正常显示 不是在IE中不能正常显示,IE中是正常的
而是在IE中下载会有一个打开按钮,(类似在线查看),点此按钮,比如说是一个word文档
就会自动用word打开,此时,在word文档的标题为转码后的字符串,不是显示正常的(有中文的话)

这个问题如果是jsp的,IE6没有问题

但是asp.net就是有,不知道怎么回事

IE8+是会正常显示中文的,不会任何问题
fei07100107 2011-10-10
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 lcaiyhh 的回复:]
这个不是直接点击文件进行下载(http://www.xx.com/1.rar)的,
是自己写的一个函数输出文件流到Response里的。例如点击一个按钮,输出流,强制浏览器打开下载对话框 保存文件。


C# code


protected void Button3_Click(object sender, EventArgs e)
{
string f……
[/Quote]

经测试,IE6下面标题依然是一串% 形式的,没有改变
IE8下面标题显示正常
看不出来和Urlencode有什么区别
gw6328 2011-10-10
  • 打赏
  • 举报
回复
分浏览器来处理。貌似我遇到过的就是ie与ff不同。
lcaiyhh 2011-10-10
  • 打赏
  • 举报
回复
这个不是直接点击文件进行下载(http://www.xx.com/1.rar)的,
是自己写的一个函数输出文件流到Response里的。例如点击一个按钮,输出流,强制浏览器打开下载对话框 保存文件。


protected void Button3_Click(object sender, EventArgs e)
{
string fileName = "aaa.txt";//客户端保存的文件名
string filePath = Server.MapPath("DownLoad/aaa.txt");//路径
System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);
if (fileInfo.Exists == true)
{
const long ChunkSize = 102400;//100K 每次读取文件,只读取100K,这样可以缓解服务器的压力
byte[] buffer = new byte[ChunkSize];
Response.Clear();
System.IO.FileStream iStream = System.IO.File.OpenRead(filePath);
long dataLengthToRead = iStream.Length;//获取下载的文件总大小
Response.ContentType = "application/octet-stream";
switch (Request.Browser.Browser)
{
case "Firefox": Response.AddHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\""); break;
case "AppleMAC-Safari": Response.AddHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\""); break;
case "IE": Response.AddHeader("Content-Disposition", "attachment;filename=" + ReplaceEtension(ToHexString(fileName))); break;
default: Response.AddHeader("Content-Disposition", "attachment;filename=" + ReplaceEtension(ToHexString(fileName))); break;
}
while (dataLengthToRead > 0 && Response.IsClientConnected)
{
int lengthRead = iStream.Read(buffer, 0, Convert.ToInt32(ChunkSize));//读取的大小
Response.OutputStream.Write(buffer, 0, lengthRead);
Response.Flush();
dataLengthToRead = dataLengthToRead - lengthRead;
}
Response.Close();
}
}

再把我那几个函数加进去,肯定没问题的。

还有个问题说明一下,长文件名IE6是无法解决的,就是编码后,字符长度超过150几位的话,会自动截取。
(IE6,只支持这么长,其他浏览器没问题)
lcaiyhh 2011-10-10
  • 打赏
  • 举报
回复
...前段时间也遇到这个问题了。索性贴出代码,经测试,IE+,火狐,谷歌下都正常
楼主 解决问题了·请给分哈
fileName = "sfsdf.中文{}{}$#%##~!@.jsp";
switch (Context.Request.Browser.Browser)
{
case "Firefox": Context.Response.AddHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\""); break;
case "AppleMAC-Safari": Context.Response.AddHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\""); break;
case "IE": Context.Response.AddHeader("Content-Disposition", "attachment;filename=" + ReplaceEtension(ToHexString(fileName))); break;
default: Context.Response.AddHeader("Content-Disposition", "attachment;filename=" + ReplaceEtension(ToHexString(fileName))); break;
}
Context.Response.ContentEncoding = System.Text.Encoding.UTF8;



private string ReplaceEtension(string filename)
{
string tempEtension = Path.GetExtension(filename);
string newfilename = filename.Replace(tempEtension, "");
return newfilename.Replace(".", "%2E") + tempEtension;
//return newfilename + tempEtension;
}


/// <summary>
/// 为字符串中的非英文字符编码
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
private static string ToHexString(string s)
{
char[] chars = s.ToCharArray();
StringBuilder builder = new StringBuilder();
for (int index = 0; index < chars.Length; index++)
{
bool needToEncode = NeedToEncode(chars[index]);
if (needToEncode)
{
string encodedString = ToHexString(chars[index]);
builder.Append(encodedString);
}
else
{
builder.Append(chars[index]);
}
}

return builder.ToString();
}

/// <summary>
///指定 一个字符是否应该被编码
/// </summary>
/// <param name="chr"></param>
/// <returns></returns>
private static bool NeedToEncode(char chr)
{
string reservedChars = "$-_.+!*'(),@=&";

if (chr > 127)
return true;
if (char.IsLetterOrDigit(chr) || reservedChars.IndexOf(chr) >= 0)
return false;

return true;
}

/// <summary>
/// 为非英文字符串编码
/// </summary>
/// <param name="chr"></param>
/// <returns></returns>
private static string ToHexString(char chr)
{
UTF8Encoding utf8 = new UTF8Encoding();
byte[] encodedBytes = utf8.GetBytes(chr.ToString());
StringBuilder builder = new StringBuilder();
for (int index = 0; index < encodedBytes.Length; index++)
{
builder.AppendFormat("%{0}", Convert.ToString(encodedBytes[index], 16));
}
return builder.ToString();
}
archu 2011-10-10
  • 打赏
  • 举报
回复
[Quote=引用 42 楼 fei07100107 的回复:]

引用 41 楼 lcaiyhh 的回复:
明白你说的意思了,
弹出的对话框 的三个按钮 打开,保存,取消
你的说直接保存是OK的,如果点打开(如果是DOC),就会用WORD直接打开,存储的是临时文件,这时WORD程序的标题栏,是编码后的特殊字符,对么?

SomethingJack 40楼 的代码和我的是一样的。
现在一切都是正常的,使用IE6来使用也不会有任何问题,就是说打开的时候……
[/Quote]

呵呵,我已经确认了这是IE浏览器的问题了,而且前面给了你详细回复。如果你真有jsp或者其它链接是正常的,贴个链接出来我帮你研究下它为什么没问题。

回头我再给你发个blog专门说这个问题的。
lcaiyhh 2011-10-10
  • 打赏
  • 举报
回复
哦·对了·你用的是IE,不用火狐

用HttpAnalyzerFullV3这个工具吧,也能查看,这是个网络数据抓包工具,安装好后,启动监视即可,
看看用JSP,跟ASPX,在IE6下返回的HTTP头有什么不一样,你就会明白了!
lcaiyhh 2011-10-10
  • 打赏
  • 举报
回复
教你个办法,用火狐装上Firebug插件,
打开Firebug插件
用jsp的方式 下载一次文件,

在控制栏 选项卡里,看看 这次下载请求,返回的HTTP头里,是些什么东西,看跟ASP.NET返回的有上面不一样,
然后再做调整吧
fei07100107 2011-10-10
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 lcaiyhh 的回复:]
明白你说的意思了,
弹出的对话框 的三个按钮 打开,保存,取消
你的说直接保存是OK的,如果点打开(如果是DOC),就会用WORD直接打开,存储的是临时文件,这时WORD程序的标题栏,是编码后的特殊字符,对么?
[/Quote]
SomethingJack 40楼 的代码和我的是一样的。
现在一切都是正常的,使用IE6来使用也不会有任何问题,就是说打开的时候office不能够把URL编码过的转回去了,在office标题显示的是%的形式,就是不直观

亲爱的客户又不升级IE6(IE8没有任何问题),搞得都不知道怎么解决了

使用jsp写的也不会有问题(IE6测试)

不知道是浏览器(IE)的问题,还是语言(.net)的问题
lcaiyhh 2011-10-10
  • 打赏
  • 举报
回复
明白你说的意思了,
弹出的对话框 的三个按钮 打开,保存,取消
你的说直接保存是OK的,如果点打开(如果是DOC),就会用WORD直接打开,存储的是临时文件,这时WORD程序的标题栏,是编码后的特殊字符,对么?
加载更多回复(35)
网管教程 从入门到精通软件篇 ★一。★详细的xp修复控制台命令和用法!!! 放入xp(2000)的光盘,安装候选R,修复! Windows XP(包括 Windows 2000)的控制台命令是在系统出现一些意外情况下的一种非常有效的诊断和测试以及恢复系统功能的工具。小编的确一直都想把这方面的命令做个总结,这次辛苦老范给我们整理了这份实用的秘笈。   Bootcfg   bootcfg 命令启动配置和故障恢复(对于大多数计算机,即 boot.ini 文件)。   含有下列参数的 bootcfg 命令仅在使用故障恢复控制台才可用。可在命令提示符下使用带有不同参数的 bootcfg 命令。   用法:   bootcfg /default  设置默认引导项。   bootcfg /add    向引导列表中添加 Windows 安装。   bootcfg /rebuild  重复全部 Windows 安装过程并允许用户选择要添加的内容。   注意:使用 bootcfg /rebuild 之前,应先通过 bootcfg /copy 命令备份 boot.ini 文件。   bootcfg /scan    扫描用于 Windows 安装的所有磁盘并显示结果。   注意:这些结果被静态存储,并用于本次会话。如果在本次会话期间磁盘配置发生变化,为获得更新的扫描,必须先重新启动计算机,然后再次扫描磁盘。   bootcfg /list   列出引导列表中已有的条目。   bootcfg /disableredirect 在启动引导程序中禁用重定向。   bootcfg /redirect [ PortBaudRrate] |[ useBiosSettings]   在启动引导程序中通过指定配置启用重定向。   范例: bootcfg /redirect com1 115200 bootcfg /redirect useBiosSettings   hkdsk   创建并显示磁盘的状态报告。Chkdsk 命令还可列出并纠正磁盘上的错误。   含有下列参数的 chkdsk 命令仅在使用故障恢复控制台才可用。可在命令提示符下使用带有不同参数的 chkdsk 命令。   vol [drive:] [ chkdsk [drive:] [/p] [/r]   参数  无   如果不带任何参数,chkdsk 将显示当前驱动器中的磁盘状态。 drive: 指定要 chkdsk 检查的驱动器。 /p   即使驱动器不在 chkdsk 的检查范围内,也执行彻底检查。该参数不对驱动器做任何更改。 /r   找到坏扇区并恢复可读取的信息。隐含着 /p 参数。   注意 Chkdsk 命令需要 Autochk.exe 文件。如果不能在启动目录(默认为 %systemroot%System32)中找到该文件,将试着在 Windows 安装 CD 中找到它。如果有多引导系统的计算机,必须保证是在包含 Windows 的驱动器上使用该命令。 Diskpart   创建和删除硬盘驱动器上的分区。diskpart 命令仅在使用故障恢复控制台才可用。   diskpart [ /add |/delete] [device_name |drive_name |partition_name] [size]   参数 无   如果不带任何参数,diskpart 命令将启动 diskpart 的 Windows 字符模式版本。   /add   创建新的分区。   /delete   删除现有分区。   device_name   要创建或删除分区的设备。设备名称可从 map 命令的输出获得。例如,设备名称:   DeviceHardDisk0   drive_name   以驱动器号表示的待删除分区。仅与 /delete 同使用。以下是驱动器名称的范例:   D:   partition_name   以分区名称表示的待删除分区。可代替 drive_name 使用。仅与 /delete 同使用。以下是分区名称的范例:   DeviceHardDisk0Partition1    大小   要创建的分区大小,以兆字节 (MB)表示。仅与 /add 同使用。   范例   下例将删除分区: diskpart /delete Device HardDisk0 Partition3 diskpart /delete F:   下例将在硬盘上添加一个 20 MB 的分区:   diskpart /add Device HardDisk0 20   Fixboot

62,047

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧