在ASP.NET2.0中實現文件上載
自引入 Microsoft ASP.NET 版本 1.0 之日起,就存在生成 Web 應用程序的內置方法,這些方法能夠將文件上載到宿主服務器。這是通過使用 File Field HTML 服務器控件實現的。我以前寫過一篇關于如何在 ASP.NET 應用程序中有效使用該控件的 MSDN 文章。本文將再次介紹文件上載過程,但不是使用 File Field 控件,我將向您介紹如何有效使用 ASP.NET 2.0 提供的新 FileUpload 服務器控件。
雖然本文向您介紹新增的 FileUpload 服務器控件,但現在仍然可以在應用程序中使用 File Field 控件,注意到這一點是非常重要的。
FileUpload 服務器控件示例
在 ASP.NET 1.x 中使用 File Field 控件時,必須采取一些額外的步驟才能使一切有條不紊地正常運行。例如,您需要親自將 enctype="multipart/form-data" 添加到頁面的 <form> 元素中。ASP.NET 2.0 中提供的新 FileUpload 服務器控件使將文件上載到宿主服務器的過程盡可能的簡單。
最后,您試圖允許對 HTML <input type="file">標記進行編程。該標記用于與 HTML 窗體中的文件數據一起使用。過去使用傳統的 ASP(ASP 3.0 或更早的版本)時,許多程序員使用第三方組件將文件從客戶端上載到服務器。現在,通過 .NET 和該新控件可以進行上載。清單 1 顯示如何使用 FileUpload 控件將文件上載到服務器。
注 提供 Microsoft Visual Basic 和 C# 形式的示例代碼。
清單 1. 使用 FileUpload 控件將文件上載到服務器
運行該頁,如果看看為該頁生成的源代碼,就會注意到一些問題。清單 2 列出這段源代碼。
清單 2. FileUpload 控件生成的源代碼
首先要注意的是,由于 FileUpload 控件位于該頁上,因此 ASP.NET 2.0 通過添加相應的 enctype 屬性來代替您修改該頁的 <form> 元素。您還會注意到,FileUpload 控件被轉換為一個 HTML <input type="file">元素。
清單 1 中的頁面運行后,您可以選擇一個文件,然后通過單擊該頁上的 Upload File 按鈕將它上載到服務器。針對該示例,我們需要重溫一些重要的事項,以便理解實現該操作所需的所有步驟。要使清單 1 中的示例生效,必須使服務器上的目標文件夾對于 ASP.NET 使用的帳戶是可寫的,這樣才能將文件保存到指定的文件夾中。
如果您認為自己的 ASP.NET 帳戶不能寫入希望的文件夾,則只需打開 Microsoft Windows Explorer,然后定位到要添加該權限的文件夾即可。右擊該文件夾(本例中為 Uploads 文件夾),然后選擇 Properties。在 Properties 對話框中,單擊 Security 選項卡,確保列表中包括 ASP.NET 機器帳戶,該帳戶具有寫入磁盤的適當權限(請參見圖 1)。

圖 1. 查看 Uploads 文件夾的 Security 選項卡
如果在 Security 選項卡下沒看到 ASP.NET 機器帳戶,可以通過單擊 Add 按鈕并在文本區域中輸入 ASPNET(沒有期限)來添加該帳戶,如圖 2 所示。

圖 2. 將 ASP.NET 機器帳戶添加到文件夾安全性定義中
單擊 OK,將 ASP.NET 機器帳戶添加到列表中。在此,請確保為該帳戶賦予了適當的權限,然后單擊 OK,這樣就準備就緒了。
該頁上的 Submit 按鈕會引發 Button1_Click 事件發生。該事件上載文件,然后顯示一條消息,通過發布有關已上載文件的信息來告訴您上載是否成功。如果上載失敗,則該頁顯示一條描述上載失敗原因的錯誤消息。
通過使用將自己轉換為<input type="file"> 標記的 FileUpload 控件,瀏覽器自動將一個 Browse 按鈕放在 ASP.NET 頁上的文本字段旁邊。無需進行任何編程,就會出現這種情況。當最終用戶單擊 Browse 按鈕時,他可以瀏覽本地文件系統以查找要上載到服務器的文件。如圖 3 所示。單擊 Open 將把文件名和該文件的路徑放到文本字段中。

圖 3. 選擇文件
解決文件大小限制
您可能沒意識到,但對于可以使用該技術上載的文件的大小存在限制。默認情況下,使用 FileUpload 控件上載到服務器的文件最大為 4MB 左右。不能上載超過該限制的任何內容。
然而,關于 .NET 的重要一點是,它通常會提供一種規避限制的方法。您通常可以更改正在使用的默認設置。要更改大小限制,可以在 web.config.comments 文件(可以在 C:WINDOWSMicrosoft.NETFrameworkv2.0.50727CONFIG 的 ASP.NET 2.0 配置文件夾中找到)或應用程序的 web.config 文件中進行一些改動。
在 web.config.comments 文件中,查找一個名為 <executionTimeout>的節點,如下所示:
在這個節點上進行了許多操作,但負責上載文件大小的設置是 maxRequestLength 屬性。默認情況下,該屬性設置為 4096 千字節 (KB)。只需更改此值,就可以增加可上載到服務器的文件大小。如果想要允許將 10 兆字節 (MB) 的文件上載到服務器,則將 maxRequestLength 值設置為 11264,這意味著該應用程序允許將最大為 11000 KB 的文件上載到服務器。
在 web.config.comments 文件中進行此改動會將該設置應用于服務器上的所有應用程序。如果要將該設置僅應用于正在使用的應用程序,則將該節點應用于應用程序的 web.config 文件,覆蓋 web.config.comments 文件中的所有設置。請確保該節點位于配置文件中的 <system.web> 節點之間。
與上載文件大小限制有關的另一個設置是賦給 <httpRuntime> 節點中 executionTimeout 屬性的值。
賦給 executionTimeout 屬性的值是 ASP.NET 關閉前允許發生的上載秒數。如果要允許將更大的文件上載到服務器,則還要增加該值和 maxRequestLength 值。
增加可上載文件大小的一個缺點是,存在通過發出大量請求來攻擊服務器的黑客。要避免這種情況,可以減小允許上載的文件大小;否則,可能會發現數百個甚至上千個 10 MB 的請求訪問您的服務器。
客戶端驗證允許上載的文件類型
有幾種方法可以用來控制上載到服務器的文件類型。遺憾的是,沒有一種十全十美的方法可以防御其他人上載惡意的文件。然而,您可以采取一些步驟,以使這個允許最終用戶上載文件的過程更易于管理。
一個可用的好方法是使用 ASP.NET 免費提供的 ASP.NET 驗證控件。這些控件使您可以對正在上載的文件進行正則表達式檢查,看看文件的擴展名是否在允許上載的擴展名之列。
因為該方法強制在客戶端進行檢查,所以對于允許在客戶端使用驗證控件的瀏覽器而言,這是一個理想的選擇;如果簽名不是您允許的簽名,則該文件不能上載到服務器。清單 3 顯示一個使用驗證控件完成該任務的示例。
注 此處不介紹驗證控件的用法。有關驗證控件的完整解釋以及如何在 ASP.NET 頁中使用它們,請參閱相關資料。
清單 3. 使用驗證控件限制上載到服務器的文件類型
這個簡單的 ASP.NET 頁使用驗證控件,這樣最終用戶就只能將 .mp3、.mpeg 或 .m3u 文件上載到服務器。如果文件類型不是以上可選的文件類型,則 Validation 控件向屏幕拋出一個異常。如圖 4 所示。

圖 4. 使用驗證控件驗證文件類型
對于上載到服務器的文件,使用 Validation 控件不是一個對其進行控制的有效方法。更改一個文件的文件擴展名并不太困難,因此擴展名將被接受并上載到服務器,從而可以避開這個簡單的安全模型。
增加服務器端文件類型驗證
您剛才看到一種將一些 ASP.NET 驗證服務器控件添加到 ASP.NET 頁,以便在客戶端對文件擴展名進行驗證(以文本方式)的簡單方法。現在,讓我們看看如何在服務器端執行類似的操作。如清單 4 所示。
清單 4. 檢查服務器上的文件類型
現在,通過在 System.IO.Path 命名空間中使用 GetExtension 方法,基本可以執行相同的操作。對于最終用戶而言,只需將文件擴展名更改為可以生效的名稱并將更改的文件上載到宿主服務器的功能不會有所影響,注意到這一點非常重要。
同時上載多個文件
目前為止,已經有幾個不錯的示例說明了如何不費周折地將文件上載到服務器。現在,讓我們看看如何從一個頁面將多個文件上載到服務器。
Microsoft .NET Framework 中沒有任何內置功能使您可以從一個 ASP.NET 頁上載多個文件。然而,只需要少量工作,您就可以像過去使用 .NET 1.x 那樣完成此任務。
方法是將 System.IO 類導入到 ASP.NET 頁中,然后使用 HttpFileCollection 類捕獲通過 Request 對象發送來的所有文件。該方法使您可以從一個頁面上載所需數量的文件。
如果需要,您完全可以分別處理該頁上的每個 FileUpload 控件,如清單 5 所示。
清單 5. 分別處理每個 FileUpload 控件
該方法有效,但可能存在這種情況:您要使用 HttpFileCollection 類處理文件,特別是在處理動態生成的服務器控件列表時。
針對這種情況的示例,您可以生成一個 ASP.NET 頁,該頁有三個 FileUpload 控件和一個 Submit 按鈕(使用 Button 控件)。用戶單擊 Submit 按鈕并且文件被發布到服務器之后,隱藏的代碼將文件保存到服務器上的特定位置。保存文件后,在 ASP.NET 頁上顯示已發布的文件信息(請參見清單 6)。
清單 6. 將多個文件上載到服務器
最終用戶最多可以選擇四個文件,然后單擊 Upload Files 按鈕,該按鈕會初始化 Button1_Click 事件。使用 HttpFileCollection 類和 Request.Files 屬性使您可以控制從該頁上載的所有文件。當這些文件處于此狀態時,您可以對它們進行任何操作。在本例中,檢查文件的屬性并將它們輸出到屏幕上。最后,這些文件保存到服務器根目錄的 Uploads 文件夾中。該操作的結果如圖 5 所示。

圖 5. 一次將一個 ASP.NET 頁上的四個文件上載到服務器
您可能已經注意到,該示例有趣的一點是,文件輸入文本框的狀態沒有通過回發進行保存。在圖 5 中您可以看到這一點。在 ASP.NET 中,無法保存文件輸入文本框的狀態,因為這么做可能會引發安全風險。
小結
ASP.NET 提供的 FileUpload 服務器控件是一個強大的控件,在 Active Server Pages 3.0 時代實現該控件非常困難。這個新增的功能允許最終用戶將一個或多個文件上載到服務器。請記住,通過利用 web.config.comments 或 web.config 文件中的設置,您可以控制文件的大小。
雖然本文向您介紹新增的 FileUpload 服務器控件,但現在仍然可以在應用程序中使用 File Field 控件,注意到這一點是非常重要的。
FileUpload 服務器控件示例
在 ASP.NET 1.x 中使用 File Field 控件時,必須采取一些額外的步驟才能使一切有條不紊地正常運行。例如,您需要親自將 enctype="multipart/form-data" 添加到頁面的 <form> 元素中。ASP.NET 2.0 中提供的新 FileUpload 服務器控件使將文件上載到宿主服務器的過程盡可能的簡單。
最后,您試圖允許對 HTML <input type="file">標記進行編程。該標記用于與 HTML 窗體中的文件數據一起使用。過去使用傳統的 ASP(ASP 3.0 或更早的版本)時,許多程序員使用第三方組件將文件從客戶端上載到服務器。現在,通過 .NET 和該新控件可以進行上載。清單 1 顯示如何使用 FileUpload 控件將文件上載到服務器。
注 提供 Microsoft Visual Basic 和 C# 形式的示例代碼。
清單 1. 使用 FileUpload 控件將文件上載到服務器
Visual Basic <%@ Page Language="VB" %> <script runat="server"> Protected Sub Button1_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) If FileUpload1.HasFile Then Try FileUpload1.SaveAs("C:Uploads" & _ FileUpload1.FileName) Label1.Text = "File name: " & _ FileUpload1.PostedFile.FileName & "<br>" & _ "File Size: " & _ FileUpload1.PostedFile.ContentLength & " kb<br>" & _ "Content type: " & _ FileUpload1.PostedFile.ContentType Catch ex As Exception Label1.Text = "ERROR: " & ex.Message.ToString() End Try Else Label1.Text = "You have not specified a file." End If End Sub </script> <HTML xmlns="http://www.w3.org/1999/xHTML" > <head runat="server"> <title>Upload Files</title> </head> <body> <form id="form1" runat="server"> <div> <ASP:FileUpload ID="FileUpload1" runat="server" /><br /> <br /> <ASP:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Upload File" /> <br /> <br /> <ASP:Label ID="Label1" runat="server"></ASP:Label></div> </form> </body> </HTML> C# <%@ Page Language="C#" %> <script runat="server"> protected void Button1_Click(object sender, EventArgs e) { if (FileUpload1.HasFile) try { FileUpload1.SaveAs("C:\Uploads\" + FileUpload1.FileName); Label1.Text = "File name: " + FileUpload1.PostedFile.FileName + "<br>" + FileUpload1.PostedFile.ContentLength + " kb<br>" + "Content type: " + FileUpload1.PostedFile.ContentType; } catch (Exception ex) { Label1.Text = "ERROR: " + ex.Message.ToString(); } else { Label1.Text = "You have not specified a file."; } } </script> <HTML xmlns="http://www.w3.org/1999/xHTML" > <head runat="server"> <title>Upload Files</title> </head> <body> <form id="form1" runat="server"> <div> <ASP:FileUpload ID="FileUpload1" runat="server" /><br /> <br /> <ASP:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Upload File" /> <br /> <br /> <ASP:Label ID="Label1" runat="server"></ASP:Label></div> </form> </body> </HTML> |
運行該頁,如果看看為該頁生成的源代碼,就會注意到一些問題。清單 2 列出這段源代碼。
清單 2. FileUpload 控件生成的源代碼
<HTML xmlns="http://www.w3.org/1999/xHTML" > <head><title> Upload Files </title></head> <body> <form name="form1" method="post" action="MyFileUpload.ASPx" id="form1" enctype="multipart/form-data"> <div> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value=" |
首先要注意的是,由于 FileUpload 控件位于該頁上,因此 ASP.NET 2.0 通過添加相應的 enctype 屬性來代替您修改該頁的 <form> 元素。您還會注意到,FileUpload 控件被轉換為一個 HTML <input type="file">元素。
清單 1 中的頁面運行后,您可以選擇一個文件,然后通過單擊該頁上的 Upload File 按鈕將它上載到服務器。針對該示例,我們需要重溫一些重要的事項,以便理解實現該操作所需的所有步驟。要使清單 1 中的示例生效,必須使服務器上的目標文件夾對于 ASP.NET 使用的帳戶是可寫的,這樣才能將文件保存到指定的文件夾中。
如果您認為自己的 ASP.NET 帳戶不能寫入希望的文件夾,則只需打開 Microsoft Windows Explorer,然后定位到要添加該權限的文件夾即可。右擊該文件夾(本例中為 Uploads 文件夾),然后選擇 Properties。在 Properties 對話框中,單擊 Security 選項卡,確保列表中包括 ASP.NET 機器帳戶,該帳戶具有寫入磁盤的適當權限(請參見圖 1)。

圖 1. 查看 Uploads 文件夾的 Security 選項卡
如果在 Security 選項卡下沒看到 ASP.NET 機器帳戶,可以通過單擊 Add 按鈕并在文本區域中輸入 ASPNET(沒有期限)來添加該帳戶,如圖 2 所示。

圖 2. 將 ASP.NET 機器帳戶添加到文件夾安全性定義中
單擊 OK,將 ASP.NET 機器帳戶添加到列表中。在此,請確保為該帳戶賦予了適當的權限,然后單擊 OK,這樣就準備就緒了。
該頁上的 Submit 按鈕會引發 Button1_Click 事件發生。該事件上載文件,然后顯示一條消息,通過發布有關已上載文件的信息來告訴您上載是否成功。如果上載失敗,則該頁顯示一條描述上載失敗原因的錯誤消息。
通過使用將自己轉換為<input type="file"> 標記的 FileUpload 控件,瀏覽器自動將一個 Browse 按鈕放在 ASP.NET 頁上的文本字段旁邊。無需進行任何編程,就會出現這種情況。當最終用戶單擊 Browse 按鈕時,他可以瀏覽本地文件系統以查找要上載到服務器的文件。如圖 3 所示。單擊 Open 將把文件名和該文件的路徑放到文本字段中。

圖 3. 選擇文件
解決文件大小限制
您可能沒意識到,但對于可以使用該技術上載的文件的大小存在限制。默認情況下,使用 FileUpload 控件上載到服務器的文件最大為 4MB 左右。不能上載超過該限制的任何內容。
然而,關于 .NET 的重要一點是,它通常會提供一種規避限制的方法。您通常可以更改正在使用的默認設置。要更改大小限制,可以在 web.config.comments 文件(可以在 C:WINDOWSMicrosoft.NETFrameworkv2.0.50727CONFIG 的 ASP.NET 2.0 配置文件夾中找到)或應用程序的 web.config 文件中進行一些改動。
在 web.config.comments 文件中,查找一個名為 <executionTimeout>的節點,如下所示:
<httpRuntime executionTimeout="110" maxRequestLength="4096" requestLengthDiskThreshold="80" useFullyQualifiedRedirectUrl="false" minFreeThreads="8" minLocalRequestFreeThreads="4" appRequestQueueLimit="5000" enableKernelOutputCache="true" enableVersionHeader="true" requireRootedSaveASPath="true" enable="true" shutdownTimeout="90" delayNotificationTimeout="5" waitChangeNotification="0" maxWaitChangeNotification="0" enableHeaderChecking="true" sendCacheControlHeader="true" apartmentThreading="false" /> |
在這個節點上進行了許多操作,但負責上載文件大小的設置是 maxRequestLength 屬性。默認情況下,該屬性設置為 4096 千字節 (KB)。只需更改此值,就可以增加可上載到服務器的文件大小。如果想要允許將 10 兆字節 (MB) 的文件上載到服務器,則將 maxRequestLength 值設置為 11264,這意味著該應用程序允許將最大為 11000 KB 的文件上載到服務器。
在 web.config.comments 文件中進行此改動會將該設置應用于服務器上的所有應用程序。如果要將該設置僅應用于正在使用的應用程序,則將該節點應用于應用程序的 web.config 文件,覆蓋 web.config.comments 文件中的所有設置。請確保該節點位于配置文件中的 <system.web> 節點之間。
與上載文件大小限制有關的另一個設置是賦給 <httpRuntime> 節點中 executionTimeout 屬性的值。
賦給 executionTimeout 屬性的值是 ASP.NET 關閉前允許發生的上載秒數。如果要允許將更大的文件上載到服務器,則還要增加該值和 maxRequestLength 值。
增加可上載文件大小的一個缺點是,存在通過發出大量請求來攻擊服務器的黑客。要避免這種情況,可以減小允許上載的文件大小;否則,可能會發現數百個甚至上千個 10 MB 的請求訪問您的服務器。
客戶端驗證允許上載的文件類型
有幾種方法可以用來控制上載到服務器的文件類型。遺憾的是,沒有一種十全十美的方法可以防御其他人上載惡意的文件。然而,您可以采取一些步驟,以使這個允許最終用戶上載文件的過程更易于管理。
一個可用的好方法是使用 ASP.NET 免費提供的 ASP.NET 驗證控件。這些控件使您可以對正在上載的文件進行正則表達式檢查,看看文件的擴展名是否在允許上載的擴展名之列。
因為該方法強制在客戶端進行檢查,所以對于允許在客戶端使用驗證控件的瀏覽器而言,這是一個理想的選擇;如果簽名不是您允許的簽名,則該文件不能上載到服務器。清單 3 顯示一個使用驗證控件完成該任務的示例。
注 此處不介紹驗證控件的用法。有關驗證控件的完整解釋以及如何在 ASP.NET 頁中使用它們,請參閱相關資料。
清單 3. 使用驗證控件限制上載到服務器的文件類型
<ASP:FileUpload ID="FileUpload1" runat="server" /><br /> <br /> <ASP:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Upload File" /> <br /> <br /> <ASP:Label ID="Label1" runat="server"></ASP:Label> <ASP:RegularExpressionValidator id="RegularExpressionValidator1" runat="server" ErrorMessage="Only mp3, m3u or mpeg files are allowed!" ValidationExpression="^(([a-zA-Z]:)|(\{2}w+)$?)(\(w[w].*)) +(.mp3|.MP3|.mpeg|.MPEG|.m3u|.M3U)$" ControlToValidate="FileUpload1"></ASP:RegularExpressionValidator> <br /> <ASP:RequiredFieldValidator id="RequiredFieldValidator1" runat="server" ErrorMessage="This is a required field!" ControlToValidate="FileUpload1"></ASP:RequiredFieldValidator> |
這個簡單的 ASP.NET 頁使用驗證控件,這樣最終用戶就只能將 .mp3、.mpeg 或 .m3u 文件上載到服務器。如果文件類型不是以上可選的文件類型,則 Validation 控件向屏幕拋出一個異常。如圖 4 所示。

圖 4. 使用驗證控件驗證文件類型
對于上載到服務器的文件,使用 Validation 控件不是一個對其進行控制的有效方法。更改一個文件的文件擴展名并不太困難,因此擴展名將被接受并上載到服務器,從而可以避開這個簡單的安全模型。
增加服務器端文件類型驗證
您剛才看到一種將一些 ASP.NET 驗證服務器控件添加到 ASP.NET 頁,以便在客戶端對文件擴展名進行驗證(以文本方式)的簡單方法。現在,讓我們看看如何在服務器端執行類似的操作。如清單 4 所示。
清單 4. 檢查服務器上的文件類型
Visual Basic Protected Sub Button1_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) If FileUpload1.HasFile Then Dim fileExt As String fileExt = System.IO.Path.GetExtension(FileUpload1.FileName) If (fileExt = ".mp3") Then Try FileUpload1.SaveAs("C:Uploads" & _ FileUpload1.FileName) Label1.Text = "File name: " & _ FileUpload1.PostedFile.FileName & "" & _ "File Size: " & _ FileUpload1.PostedFile.ContentLength & " kb" & _ "Content type: " & _ FileUpload1.PostedFile.ContentType Catch ex As Exception Label1.Text = "ERROR: " & ex.Message.ToString() End Try Else Label1.Text = "Only .mp3 files allowed!" End If Else Label1.Text = "You have not specified a file." End If End SubC# protected void Button1_Click(object sender, EventArgs e) { if (FileUpload1.HasFile) { string fileExt = System.IO.Path.GetExtension(FileUpload1.FileName); if (fileExt == ".mp3") { try { FileUpload1.SaveAs("C:\Uploads\" + FileUpload1.FileName); Label1.Text = "File name: " + FileUpload1.PostedFile.FileName + "" + FileUpload1.PostedFile.ContentLength + " kb" + "Content type: " + FileUpload1.PostedFile.ContentType; } catch (Exception ex) { Label1.Text = "ERROR: " + ex.Message.ToString(); } } else { Label1.Text = "Only .mp3 files allowed!"; } } else { Label1.Text = "You have not specified a file."; } } |
現在,通過在 System.IO.Path 命名空間中使用 GetExtension 方法,基本可以執行相同的操作。對于最終用戶而言,只需將文件擴展名更改為可以生效的名稱并將更改的文件上載到宿主服務器的功能不會有所影響,注意到這一點非常重要。
同時上載多個文件
目前為止,已經有幾個不錯的示例說明了如何不費周折地將文件上載到服務器。現在,讓我們看看如何從一個頁面將多個文件上載到服務器。
Microsoft .NET Framework 中沒有任何內置功能使您可以從一個 ASP.NET 頁上載多個文件。然而,只需要少量工作,您就可以像過去使用 .NET 1.x 那樣完成此任務。
方法是將 System.IO 類導入到 ASP.NET 頁中,然后使用 HttpFileCollection 類捕獲通過 Request 對象發送來的所有文件。該方法使您可以從一個頁面上載所需數量的文件。
如果需要,您完全可以分別處理該頁上的每個 FileUpload 控件,如清單 5 所示。
清單 5. 分別處理每個 FileUpload 控件
Visual BasicIf FileUpload1.HasFile Then ' Handle file End If If FileUpload2.HasFile Then ' Handle file End If C# if (FileUpload1.HasFile) { // Handle file } if (FileUpload2.HasFile) { // Handle file } |
該方法有效,但可能存在這種情況:您要使用 HttpFileCollection 類處理文件,特別是在處理動態生成的服務器控件列表時。
針對這種情況的示例,您可以生成一個 ASP.NET 頁,該頁有三個 FileUpload 控件和一個 Submit 按鈕(使用 Button 控件)。用戶單擊 Submit 按鈕并且文件被發布到服務器之后,隱藏的代碼將文件保存到服務器上的特定位置。保存文件后,在 ASP.NET 頁上顯示已發布的文件信息(請參見清單 6)。
清單 6. 將多個文件上載到服務器
Visual Basic Protected Sub Button1_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Dim filepath As String = "C:Uploads" Dim uploadedFiles As HttpFileCollection = Request.Files Dim i As Integer = 0 Do Until i = uploadedFiles.Count Dim userPostedFile As HttpPostedFile = uploadedFiles(i) Try If (userPostedFile.ContentLength > 0) Then Label1.Text += "File #" & (i + 1) & "" Label1.Text += "File Content Type: " & _ userPostedFile.ContentType & "" Label1.Text += "File Size: " & _ userPostedFile.ContentLength & "kb" Label1.Text += "File Name: " & _ userPostedFile.FileName & "" userPostedFile.SaveAs(filepath & "" & _ System.IO.Path.GetFileName(userPostedFile.FileName)) Label1.Text += "Location where saved: " & _ filepath & "" & _ System.IO.Path.GetFileName(userPostedFile.FileName) & _ " " End If Catch ex As Exception Label1.Text += "Error:" & ex.Message End Try i += 1 Loop End SubC# protected void Button1_Click(object sender, EventArgs e) { string filepath = "C:\Uploads"; HttpFileCollection uploadedFiles = Request.Files; for (int i = 0; i < uploadedFiles.Count; i++) { HttpPostedFile userPostedFile = uploadedFiles[i]; try { if (userPostedFile.ContentLength > 0 ) { Label1.Text += "File #" + (i+1) + ""; Label1.Text += "File Content Type: " + userPostedFile.ContentType + ""; Label1.Text += "File Size: " + userPostedFile.ContentLength + "kb"; Label1.Text += "File Name: " + userPostedFile.FileName + ""; userPostedFile.SaveAs(filepath + "\" + System.IO.Path.GetFileName(userPostedFile.FileName)); Label1.Text += "Location where saved: " + filepath + "\" + System.IO.Path.GetFileName(userPostedFile.FileName) + " "; } } catch (Exception Ex) { Label1.Text += "Error: " + Ex.Message; } } } |
最終用戶最多可以選擇四個文件,然后單擊 Upload Files 按鈕,該按鈕會初始化 Button1_Click 事件。使用 HttpFileCollection 類和 Request.Files 屬性使您可以控制從該頁上載的所有文件。當這些文件處于此狀態時,您可以對它們進行任何操作。在本例中,檢查文件的屬性并將它們輸出到屏幕上。最后,這些文件保存到服務器根目錄的 Uploads 文件夾中。該操作的結果如圖 5 所示。

圖 5. 一次將一個 ASP.NET 頁上的四個文件上載到服務器
您可能已經注意到,該示例有趣的一點是,文件輸入文本框的狀態沒有通過回發進行保存。在圖 5 中您可以看到這一點。在 ASP.NET 中,無法保存文件輸入文本框的狀態,因為這么做可能會引發安全風險。
小結
ASP.NET 提供的 FileUpload 服務器控件是一個強大的控件,在 Active Server Pages 3.0 時代實現該控件非常困難。這個新增的功能允許最終用戶將一個或多個文件上載到服務器。請記住,通過利用 web.config.comments 或 web.config 文件中的設置,您可以控制文件的大小。