撐到大三了,結果發現周圍的同學更加墮落了,尤其是某些人,表面上看起來很認真,實際上三天打魚,兩天曬網,結果一事無成,卻還要抱怨學校教育失敗。
為了吸取他們的教訓,就算是一個小小的編碼問題,我也要努力解決。因為學習的機會一向都在,只是自己有沒有去努力而已。
之前做個班級站點的課程設計,用一天半的時間做完雖然各方面不咋樣,但麻雀雖小,五臟俱在,功能流程還是挺完整的。
就算是一個小小的課程設計,在這短暫的時間內,也遇到了不少問題,有大有小。
先說文件下載這塊。
文件下載一般都是需要一個文件選擇對話框來選擇存放文件的地方。我們可以自己做一個,但簡單的方面就是利用瀏覽器的現成功能。
所有的瀏覽器都包括文件下載功能,但文件選擇對話框卻不是每個瀏覽器都有提供。這里我只選擇我常用的兩個瀏覽器:谷歌瀏覽器和搜狗瀏覽器。
先來一個小例子:
public ActionResult Index() { var path = Server.MapPath("~/frog.jpg.jpg"); return File(path, "iamge/jpeg"); }
這里是下載工程根目錄下的frog.jpg.jpg。
代碼非常簡短,只有兩行,但效果卻不差:
這是搜狗瀏覽器上的效果,如果是谷歌瀏覽器,則是直接下載下來,但是文件並不是我們的文件名,甚至格式也不一樣,就是一個奇怪的名為"下載"的文件。
首先是解釋上面兩行代碼的原理:
Server.MapPath()的參數是一個虛擬路徑的,它的原理是根據提供的虛擬路徑返回一個虛擬路徑對應的物理路徑,而且參數路徑必須是虛擬路徑。我們服務器上傳的文件都是放在服務器的一個路徑下,這個路徑是物理路徑,但是打開文件的URL卻是虛擬路徑,這樣的好處就像是相對路徑和絕對路徑的對比,想想如果我們將文件的額存放地點放在另一個地方,如果URL為物理路徑,那么就會找不到該文件。
path現在是frog.jpg.jpg的物理路徑,然后我們要將該文件發送給瀏覽器,則需要利用FilePathResult的File(),指定發送文件的物理路徑和格式就可以了。
值得注意的是,如果是在搜狗中,指定格式是application/x-zip-compressed(zip的MIME格式)或者application/octet-stream(rar的MIME格式),在網頁上看到的將會是亂碼,但如果是谷歌,依然是上面那樣的情況,但是用壓縮文件軟件打開,就會發現里面就是我們要的文件,它確實是被下載下來了。
由於谷歌瀏覽器的行為與我們想要的效果差了太遠了,所以下面就不再討論谷歌瀏覽器的行為。
我用word文檔,Excel表格和txt文檔格式的文件分別發送給瀏覽器,結果只有txt文檔的文件中的內容能夠正常顯示在網頁中,其他都是亂碼,可見,網頁能夠直接打開的文件格式是有限的,至少需要第三方軟件打開的文件是無法打開的。
上面這些都不是重點,只是我的一點好奇心而已。現在我們進入重點,就是讓瀏覽器提供下載對話框。
要實現這樣的功能,上面的代碼是不行的,至少我這邊是不行的,要用下面的代碼:
var path = Server.MapPath("~/1.txt"); var name = Path.GetFileName(path); return File(path, "application/zip-x-compressed", name);
然后瀏覽器的運行效果如:

這就是我們想要的結果。
我們增加了一行代碼,就是使用Path.GetFileName()來獲取指定物理路徑的文件的文件名和擴展名,然后再在File()中增加一個新的參數,該參數就是我們要下載的文件的文件名和擴展名。
但可怕的是,上面代碼中File的格式可以隨便指定,甚至可以直接為"1"(只要不是null以及""),都會提供上面的下載對話框!!這告訴我們,該下載對話框需要的並不是文件的正確格式,它需要的僅僅只是需要下載的文件的文件名(這個文件名並一定要是正確的文件名,我們可以指定新的名字,反正它就只要將該物理路徑下的那個文件下載下來就行)以及該文件的物理路徑。
必須注意的是,如果文件名包含有中文,那么它就會顯示這樣的效果:

如果想要顯示正確的中文文件名,我們可以這樣做:
return File(path, "1", Url.Encode(name));
效果就會這樣:

要實現上面的效果,我們還可以這樣做:
byte[] data = Encoding.UTF8.GetBytes("~/中國.txt"); return File(data, "1", Url.Encode("中國.txt"));
這里我們是直接將"~/中國.txt"變為byte[]數組然后發給瀏覽器,保存在中國.txt中,打開就是"~/中國.txt"。這種方式屬於FileContentResult。
大概的內容就是上面這樣,當然我們可以自定義,畢竟像是谷歌瀏覽器根本就不提供下載對話框的情況下,更加需要我們自定義下載對話框,但這里不講,先是這樣,以后再繼續補充。
