在 ASP.NET 2.0 中上傳檔案 Z

來源:互聯網
上載者:User
 在 ASP.NET 2.0 中上傳檔案 Z

轉自:

Bill Evjen
Reuters

適用於:

Microsoft ASP.NET 2.0
Microsoft Visual Web Developer 2005 Express Edition

摘要:瞭解如何使用 Microsoft ASP.NET 2.0 中新增的 FileUpload 伺服器控制項。

本頁內容
簡介
FileUpload 伺服器控制項樣本
小結

簡介

自引入 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 控制項將檔案上傳到伺服器

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="/wEPDwUJNDcxNTg5NDg3D2QWAgIEDxYCHgdlbmN0eXBlBRNtdWx0aXBhcnQvZm9yb       S1kYXRhZGQUQEUFMY1+/fp1mnrkbqmVNQIzFA==" /></div>    <div>        <input type="file" name="FileUpload1" id="FileUpload1" /><br />        <br />        <input type="submit" name="Button1" value="Upload File"          id="Button1" /> <br />        <br />        <span id="Label1"></span>    </div>    <div>   <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION"     value="/wEWAgLB+7jIAwKM54rGBv2Iz6LxVY7jWec0gZMxnuaK2ufq" /></div></form></body></HTML>

首先要注意的是,由於 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:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG 的 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 (KB)。只需更改此值,就可以增加可上傳到伺服器的檔案大小。如果想要允許將 10 MB (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 驗證控制項。這些控制項使您可以對正在上傳的檔案進行Regex檢查,看看檔案的副檔名是否在允許上傳的副檔名之列。

因為該方法強制在用戶端進行檢查,所以對於允許在用戶端使用驗證控制項的瀏覽器而言,這是一個理想的選擇;如果簽名不是您允許的簽名,則該檔案不能上傳到伺服器。清單 3 顯示一個使用驗證控制項完成該任務的樣本。

此處不介紹驗證控制項的用法。有關驗證控制項的完整解釋以及如何在 ASP.NET 頁中使用它們,請參閱 Validating ASP.NET Server Controls。

清單 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)___FCKpd___4quot;  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 Sub

C#

    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 Basic

If FileUpload1.HasFile Then   ' Handle fileEnd IfIf FileUpload2.HasFile Then   ' Handle fileEnd 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   LoopEnd Sub

C#

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 檔案中的設定,您可以控制檔案的大小。

關於作者

Bill Evjen 是 .NET 技術和 .NET 社區學習計劃的積極支援者。他是 Reuters 的一名技術指導,該公司是一家國際新聞和金融服務公司,位於密蘇里州的聖路易斯。Bill 是 International .NET Association (INETA) 的建立者和執行董事,該組織在全世界範圍內擁有 100,000 多名會員。Bill 還是一名作家和演講者,他的著作有 ASP.NET Professional SecretsXML Web Services for ASP.NETWeb Services EnhancementsVisual Basic .NET Bible(全部由 Wiley 出版)。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.