[ASP.NET][C#]下載檔案時中文檔名出現亂碼

負責的網站在ASP.NET網頁有一段下載Word/Excel檔案的程式碼,最近使用者要求的檔案名稱內含繁體中文字,
同事用chrome/firefox瀏覽器測試下載都很正常顯示,但用IE(版本11)開啟時,卻出現了亂碼。

 

1.準備一個中文檔名的檔案

ASP.NET MVC

2.在HomeControler中加入下載程式碼Download

public ActionResult Download()
{
    //檔案位置
    string filepath = @"E:\test\WebApplication1\中文檔名.docx";
    //檔案名稱
    string filename = Path.GetFileName(filepath);
    //讀成串流
    Stream sfilestream = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read);
    //回傳出檔案
    return File(sfilestream, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", filename);
}

3.執行下載

檔名正常顯示中文!

 

換上ASP.NET Web Form

4.先增一支Download.aspx

在Page load加入下載程式碼

protected void Page_Load(object sender, EventArgs e)
{
    string filepath = @"E:\test\WebApplication1\中文檔名.docx";
    string fileName = Path.GetFileName(filepath);

    HttpContext.Current.Response.AppendHeader("content-disposition", "attachment;filename=" + fileName);
    HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
    HttpContext.Current.Response.WriteFile(filepath);
    HttpContext.Current.Response.End();
}

5.執行下載

檔名不正常

 

找到兩個解法
  1. 將中文檔名用HttpUtility.UrlEncode以UTF8編碼系統進行QP編碼。
  2. HeaderEncoding編碼改為BIG5

 

(1)將中文檔名用HttpUtility.UrlEncode以UTF8編碼系統進行QP編碼
string fileName = HttpUtility.UrlEncode(Path.GetFileName(filepath));
//string fileName = Path.GetFileName(filepath);


HttpUtility.UrlEncode預設會以UTF8的編碼系統進行QP(Quoted-Printable)編碼,可以直接顯示的7 Bit字元(ASCII)就不用特別轉換。

  • 編碼前:.docx
  • 編碼後:%e4%b8%ad%e6%96%87%e6%aa%94%e5%90%8d.docx

除了標準ASCII,其他都會用UTF8進行編碼送到前端瀏覽器。
https://mothereff.in/utf-8

檔名可以正常顯示中文了!

 

(2)HeaderEncoding編碼改為BIG5

增加一行設定HeaderEncoding的程式碼,因為伺服器都是繁體中文,預設Encoding.Default = BIG5

HttpContext.Current.Response.HeaderEncoding = System.Text.Encoding.Default;

預設HttpContext.Current.Response.HeaderEncoding是UTF8,將編碼改為BIG5也可以解決中文檔名問題

 

都已經是UTF8編碼的網頁了,為什麼還得要將HeaderEncoding編碼改為繁體中文作業系統的BIG5才能解決???
進一步搜尋到保哥、黑暗大文章,看起來似乎與瀏覽器支援到哪一種Content-Disposition標準有關(RFC2045、2183、5987)。
好,先到此打住,來看奧運了!以後有時間再繼續深入調查。


小結:

  • 因為系統被要求要支援多國語系,暫時我們選擇第一種解法,以後出現蝌蚪文還是火星文就不怕了。
  • ASP.NET MVC已經解決了檔名有中文碼問題了。

 

參考:

HttpResponse 類別

HttpUtility.UrlEncode 

HttpResponse.HeaderEncoding

KB-Open And Download File In Chinese Filename

ASP.NET 如何設定強制下載檔案並正確處理中文檔名的問題

How to encode the filename parameter of Content-Disposition header in HTTP?