zoukankan      html  css  js  c++  java
  • 遭遇Asp.Net长文件名下载的问题和解决办法

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

    <!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->privatevoidDownload(stringID)
    {
    file=logic.GetAttachmentByID(newGuid(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编码输出中文名。

    具体代码就是:

    <!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->protectedvoidPage_Load(objectsender,EventArgse)
    {
    PostLogiclogic=newPostLogic();
    if(Request.QueryString["AID"]!=null)
    {
    Response.Clear();
    Encodingcode=Encoding.GetEncoding("gb2312");
    Response.ContentEncoding=code;
    Response.HeaderEncoding=code;//这句很重要
    Attachmentfile=logic.GetAttachmentByID(newGuid(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

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

  • 相关阅读:
    js把日期字符串转换成时间戳
    JS array 数组
    for循环中的if嵌套
    第三章:图像增强
    直方图均衡化
    第二章:数字图像处理基础
    马赫带效应
    图片格式
    4邻接,8邻接和m邻接
    第一章:绪论
  • 原文地址:https://www.cnblogs.com/ranran/p/3799848.html
Copyright © 2011-2022 走看看