zoukankan      html  css  js  c++  java
  • 遭遇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

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

    【本文章出自博客园深蓝居,转载请注明作者出处,如果您觉得博主的文章对您有很大帮助,欢迎支付宝(studyzy@163.com)对博主进行打赏。】
  • 相关阅读:
    Docker 安装各种环境
    N级树形菜单封装
    一个周期算出所有高电平的个数
    DDR3新版(3):DDR3自动读写控制器
    DDR3_新版(2):IP核再封装
    数电(6):时序逻辑电路
    Vue表单那些事
    liunx环境修改minio默认端口和后台启动
    liunx 后台启动mongodb服务
    liunx安装和部署nacos配置中心
  • 原文地址:https://www.cnblogs.com/studyzy/p/1421550.html
Copyright © 2011-2022 走看看