天天看點

遭遇Asp.Net長檔案名下載下傳的問題和解決辦法

在asp.net中寫了一個附件上傳和下載下傳的程式,附件上傳到資料庫中,然後将附件的guid儲存起來,我們可以根據guid來找到資料庫中的附件,一般附件下載下傳的代碼是:

遭遇Asp.Net長檔案名下載下傳的問題和解決辦法

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();

    }

遭遇Asp.Net長檔案名下載下傳的問題和解決辦法

這裡比較重要的就是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編碼輸出中文名。

具體代碼就是:

遭遇Asp.Net長檔案名下載下傳的問題和解決辦法

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.appendheader("content-disposition", "attachment; filename=\"" + file.filename + "\"");//這裡不進行編碼工作,直接輸出中文字元串

}

遭遇Asp.Net長檔案名下載下傳的問題和解決辦法

這樣輸出的就是長中文名了。我們再來抓包看一下http響應的頭:

content-disposition: attachment; filename="招标送檢樣機項目檢查登記表(終端)-空.xls" 

date: wed, 25 mar 2009 09:04:34 gmt

問題就這樣解決了。當然,如果使用者上傳的是一個本來就很長很長的檔案名的檔案,那也是沒有辦法的,而且資料庫中設計的字段可能也沒有那麼長。那就要在上傳的時候做好限制了。