解決Asp.net 實現文件下載時、輸出文件時文件名的中文亂碼和空格異常

在 asp.net 項目中,我們可以很方便地使用 Response.WriteFile() 方法向客戶端輸出一個文件。
實際使用 asp.net 向客戶端輸出文件流時,卻出現了異常:
1、空格問題,當原文件的文件名中含有空格時,將引發客戶端獲取到的文件名與服務器端不一致。
2、中文字符亂碼,準確的是非 ASCII 字符亂碼,當原文件的文件名中含有非 ASCII 字符時,將引發客戶端獲取到的文件名錯亂。
3、一些特殊字符不能被正常輸出(當然這裏我並不是那些不常見的符號)

注意,本文用 C# 代碼解決了在目前四種流行瀏覽器中Asp.net 輸出文件流時文件名的空格及中文字符亂碼這兩個問題。使用本文的代碼,你將可以讓 IE(Internet Explorer)、Opera、Firefox 及 Chrome 的用戶享受到沒有亂碼且支持空格文件名的文件輸出引擎,同時支持文件名中各種像“# $ % ^ &”等常見的符號,如 "Microsoft.Asp.Net.doc" 、“F ile;;!@%#^&y.doc” 這樣的文件名也可以了。請看下圖:


正確輸出的文件名

 

本文下面的內容將描述問題的具體表現,並對相關代碼做一些解釋;
如果你不需要閱讀這些內容,你可以直接下載示例代碼

 

問題現象:



對於第一個問題

在IE中,當原文件名包含空格時,默認將被改成下劃線,即“_”;如果我們在輸出文件時對文件名使用 UrlEncode() 對其進行編碼,空格將變成加號,即“+”。
在 Opera 中,文件名不需要經過 UrlEncode() 即可正確地解析,但注意經過了 UrlEncode() 後也與IE一樣,空格變成了加號。
很遺憾, Firefox 似乎並不歡迎含有空格的文件名,它會直接捨棄空格後面的部分。對於上圖中的例子,沒有進行 UrlEncode() 之前,Firefox 會得到一個“My.axd”的文件名,可以看到,它對文件類型把握並沒有錯誤(只因爲這由別外的部分負責);進行 UrlEncode() 之後,它的結果與 IE、Opera 等一致,空格變成了加號。

 

對於第二個問題

第二個問題有點複雜了。
當原文件名包含中文或其他非英文字符時,由於編碼的錯誤,默認情況很糟糕,竟然完全是無法辨識的亂碼;如果我們在輸出文件時對文件名進行 UrlEncode() 對其進行編碼,這些中文將能正確地被顯示;
但注意,問題並沒有完。在Opera 或 Firefox 中,不需要經過 UrlEncode() 即能正確地顯示了;不幸地是,如果經過了 UrlEncode(),它們將無法正確地解析。
看下面幾個圖,分別是沒有使用 UrlEncode() 編碼文件名和使用了 UrlEncode() 的時候,全英文的原文件名的文件輸出到客戶端的情況:

 

未進行 UrlEncode() 的中文文件名,IE 瀏覽器:

未進行 UrlEncode() 的中文文件名,IE 瀏覽器

 

 

已進行 UrlEncode() 的中文文件名,IE 瀏覽器:

 

已進行 UrlEncode() 的中文文件名,IE 瀏覽器

 

 

已進行 UrlEncode() 的中文文件名,Opera 瀏覽器

已進行 UrlEncode() 的中文文件名,Opera 瀏覽器

 

 

 至於 Firefox 與 Chrome 的圖就不貼了,它們與 Opera 基本一致。

 

 

問題的解決

我們可以總結如下規律:
 Internet Explorer 能在客戶端已經UrlEncode() 的字符,包括空格在內;而 Opera 等其他瀏覽器可以解析未經 UrlEncode() 的直接輸出的字符(這意味着,對於使用Opera或其他客戶端的客戶,我們不應該對它進行 UrlEncode()編碼)

爲了正確地編碼,我參考一位外國人士的代碼,使用並改進了16進制編碼方法。參考下面的代碼,可以大部分的解決問題。由於 Firefox 默認不支持中文,特別對 Firefox 用戶做了一些處理,在下面的代碼中能夠體現。

 

在輸出文件地地方使用的代碼:

 

 
下面是核心處理,應該置於上述代碼同一文件或可訪問的其他類:

 

 此外,針對一些瀏覽器做了一些特殊的處理,已經體現在本文示例代碼的註釋中。此代碼已經能非常完好地解決問題了,在 Internet Explorer 、Opera、Firefox 及 Chrome 中得到的體驗一致,支持中文,支持空格的正常輸出。

 

如果複製代碼後運行不正常,可以參考在示例代碼文件的處理情況,在這裏下載示例代碼文件,示例文件是一個 HttpHandler,因此你可能需要爲它在 Web.Config 中做相關配置,關於配置方法,請參考其他資料。你可以按你的需要來修改示例代碼。

 

本文版權:陳計節

轉載請註明出處。

歡迎訪問本文在 ciznx.com 的原地址:http://blog.ciznx.com/post/aspnetstreamdownloaddisplaynonunicodespacechar.aspx

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章