遭遇Asp.Net长文件名下载的问题和解决办法

简介:

在Asp.Net中写了一个附件上传和下载的程序,附件上传到数据库中,然后将附件的GUID保存起来,我们可以根据GUID来找到数据库中的附件,一般附件下载的代码是:


private   void  Download( string  ID)
    {
        file 
=  logic.GetAttachmentByID( new  Guid(ID));
        Response.AddHeader(
" Content-Type " , file.Type);
        Response.AppendHeader(
" Content-Disposition " " attachment; filename=\ ""  + HttpUtility.UrlEncode(file.FileName) +  " \ "" );
        Response.BinaryWrite(file.Data.ToArray());
        Response.End();
    }

这里比较重要的就是Response.AppendHeader("Content-Disposition", "attachment; filename=\"" + HttpUtility.UrlEncode(file.FileName) + "\"");这里需要对中文文件名进行编码,默认是使用的UTF8编码。但是编码后文件名就会变得很长,比如我现在有一个文件叫:

招标送检样机项目检查登记表(终端)-空.XLS

我们进行网络抓包,可以看到在下载文件的时候的HTTP响应是:

HTTP/1.1 200 OK 
Cache-Control: private 
Content-Length: 44032 
Content-Type: application/vnd.ms-excel 
Server: Microsoft-IIS/6.0 
X-Powered-By: ASP.NET 
MicrosoftSharePointTeamServices: 12.0.0.6219 
X-AspNet-Version: 2.0.50727 
Content-Disposition: attachment; filename="%e6%8b%9b%e6%a0%87%e9%80%81%e6%a3%80%e6%a0%b7%e6%9c%ba%e9%a1%b9%e7%9b%ae%e6%a3%80%e6%9f%a5%e7%99%bb%e8%ae%b0%e8%a1%a8(%e7%bb%88%e7%ab%af)-%e7%a9%ba.XLS" 
Date: Wed, 25 Mar 2009 08:00:26 GMT

可以得到编码后文件名变成了:

%e6%8b%9b%e6%a0%87%e9%80%81%e6%a3%80%e6%a0%b7%e6%9c%ba%e9%a1%b9%e7%9b%ae%e6%a3%80%e6%9f%a5%e7%99%bb%e8%ae%b0%e8%a1%a8(%e7%bb%88%e7%ab%af)-%e7%a9%ba.XLS

这都是在HTTP头里面的,由于浏览器或者其他原因,对于这么长的HTTP头,系统会对字符串进行截止,那么就会造成下载的时候文件名不全或者干脆就是乱码的情况。我试了一下,这个文件的下载在IE8里面是完全正常的,但是在IE6里面就会造成字符串截止,变成“%a0%87送检样机项目检查登记表(终端)-空.XLS”。不同的浏览器截止的还不同。

解决办法有2种,1种是限制用户上传的文件的文件名或者我们在下载的时候写代码对文件名进行截止,避免出现乱码的情况,但是这样造成的用户体验并不好。那就用第2种解决办法:不使用UTF8的UrlEncode编码,直接使用gb2312编码输出中文名。

具体代码就是:

protected   void  Page_Load( object  sender, EventArgs e)
{
    PostLogic logic 
=   new  PostLogic();
    
if  (Request.QueryString[ " AID " !=   null )
    {
        Response.Clear();
        Encoding code 
=  Encoding.GetEncoding( " gb2312 " );
        Response.ContentEncoding 
=  code;
        Response.HeaderEncoding 
=  code; // 这句很重要
        Attachment file  =  logic.GetAttachmentByID( new  Guid(Request.QueryString[ " AID " ].ToString()));
        Response.AddHeader(
" Content-Type " , file.Type);
        Response.AppendHeader(
" Content-Disposition " " attachment; filename=\ ""  + file.FileName +  " \ "" ); // 这里不进行编码工作,直接输出中文字符串
        Response.BinaryWrite(file.Data.ToArray());
        Response.End();
    }
}

 

这样输出的就是长中文名了。我们再来抓包看一下HTTP响应的头:

HTTP/1.1 200 OK 
Cache-Control: private 
Content-Length: 44032 
Content-Type: application/vnd.ms-excel 
Server: Microsoft-IIS/6.0 
X-Powered-By: ASP.NET 
MicrosoftSharePointTeamServices: 12.0.0.6219 
X-AspNet-Version: 2.0.50727 
Content-Disposition: attachment; filename="招标送检样机项目检查登记表(终端)-空.XLS" 
Date: Wed, 25 Mar 2009 09:04:34 GMT

问题就这样解决了。当然,如果用户上传的是一个本来就很长很长的文件名的文件,那也是没有办法的,而且数据库中设计的字段可能也没有那么长。那就要在上传的时候做好限制了。

本文转自深蓝居博客园博客,原文链接:http://www.cnblogs.com/studyzy/archive/2009/03/25/1421550.html,如需转载请自行联系原作者

相关文章
|
4月前
|
开发框架 前端开发 JavaScript
盘点72个ASP.NET Core源码Net爱好者不容错过
盘点72个ASP.NET Core源码Net爱好者不容错过
75 0
|
4月前
|
开发框架 .NET
ASP.NET Core NET7 增加session的方法
ASP.NET Core NET7 增加session的方法
38 0
|
7月前
|
存储 开发框架 前端开发
asp.net与asp.net优缺点及示例
asp.net与asp.net优缺点及示例
|
2月前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
32 0
|
4月前
|
SQL 开发框架 JavaScript
分享33个ASP.NET电子商务源码和40个ASP.NET控件组件源码,总有一款适合您
分享33个ASP.NET电子商务源码和40个ASP.NET控件组件源码,总有一款适合您
32 0
|
5月前
|
存储 开发框架 .NET
Asp.net就业课之Ado.net第一次课
Asp.net就业课之Ado.net第一次课
21 0
|
9月前
|
存储 开发框架 .NET
ASP.NET学生管理系统(.NET毕业设计)
ASP.NET学生管理系统(.NET毕业设计)
105 0
|
10月前
|
开发框架 前端开发 JavaScript
ASP .Net Core 中间件的使用(一):搭建静态文件服务器/访问指定文件
ASP .Net Core 中间件的使用(一):搭建静态文件服务器/访问指定文件
|
12月前
|
开发框架 .NET Apache
301重定向代码合集(iis,asp,php,asp.net,apache)
301重定向代码合集(iis,asp,php,asp.net,apache)
278 0
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
87 0