天天看點

ASP.NET 2.0進階控件之FileUpload控件

應用程式中經常需要允許使用者把檔案上傳到web伺服器。盡管在ASP.NET 1.X也可以完成該功能,但在ASP.NET 2.0中使用FileUpload控件會更簡單。

  該控件讓使用者更容易地浏覽和選擇用于上傳的檔案,它包含一個浏覽按鈕和用于輸入檔案名的文本框。隻要使用者在文本框中輸入了完全限定的檔案名,無論是直接輸入或通過浏覽按鈕選擇,都可以調用FileUpload的SaveAs方法儲存到磁盤上。

  除了從WebControl類繼承的标準成員,FileUpload控件還公開了幾個隻讀的屬性,在表5-8和表5-9列出。

  表5-8 FileUpload控件屬性

名 稱 類型 讀 寫 說 明

FileContent Stream × 傳回一個指向上傳檔案的流對象

FileName string × 傳回要上傳檔案的名稱,不包含路徑資訊

HasFile Boolean × 如果是true,則表示該控件有檔案要上傳

PostedFile HttpPostedFile × 傳回已經上傳檔案的引用。表5-9列出了它所公開的隻讀屬性

  表5-9 HttpPostedFile屬性

名 稱 類 型 讀 寫 說 明

ContentLength integer × 傳回上傳檔案的按位元組表示的檔案大小

ContentType string × 傳回上傳檔案的MIME内容類型

FileName string × 傳回檔案在用戶端的完全限定名

InputStream Stream × 傳回一個指向上傳檔案的流對象

  所有這些屬性将在下面的示例中說明。

  為了檢視FileUpload控件在實際中的運用,建立一個FileUploadDemo網站。在頁面上添加一個FileUpload控件,然後,添加兩個ASP.NET按鈕,Text屬性分别設定為Save和Display,ID分别設定為btnSave和btnDisplay。增加兩個Label控件,并分别将ID設定為lblMesage和lblDisplay。用<br/>HTML元素分隔這些控件。切換到設計視圖,通過輕按兩下每個按鈕,為它們在代碼隐藏檔案中建立具有預設名稱的Click事件處理程式。完成後的内容檔案類似于示例5-11。

  示例5-11:FileUploadDemo網站的default.aspx

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN” “http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml” >

<head runat=”server”>

 <title>FileUpload Control</title>

</head>

<body>

 <form id=”form1” runat=”server”>

 <div>

  <h1>FileUpload Control</h1>

  <asp:FileUpload ID=”FileUpload1” runat=”server” />

  <br />

  <asp:Button ID=”btnSave” runat=”server” Text=”Save” OnClick=”btnSave_Click” />

  <asp:Button ID=”btnDisplay” runat=”server” Text=”Display” OnClick=”btnDisplay_Click” />

  <br />

  <br />

  <asp:Label ID=”lblMessage” runat=”server” />

  <asp:Label ID=”lblDisplay” runat=”server” />

 </div>

 </form>

</body>

</html>

  在代碼隐藏檔案中,添加示例5-12中高亮顯示的代碼,非高亮顯示的代碼由VS2005自動建立。

  示例5-12:FileUploadDemo網站的Default.aspx.cs

using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using System.IO; // 使用Stream必需

public partial class _Default : System.Web.UI.Page

{

 protected void Page_Load(object sender, EventArgs e)

 {}

 protected void btnSave_Click(object sender, EventArgs e)

 {

  string str = “”;

  if (FileUpload1.HasFile)

  {

   try

   {

    str += “Uploading file: “ + FileUpload1.FileName;

    // 儲存檔案

    FileUpload1.SaveAs(“c:websitesuploads” + FileUpload1.FileName);

    // 顯示檔案資訊

    str += “<br/>Saved As: “ + FileUpload1.PostedFile.FileName;

    str += “<br/>File Type: “ + FileUpload1.PostedFile.ContentType;

    str += “<br/>File Length (bytes): “ + FileUpload1.PostedFile.ContentLength;

    str += “<br/>PostedFile File Name: “ + FileUpload1.PostedFile.FileName;

   }

   catch (Exception ex)

   {

    str += “<br/><b>Error</b><br/>Unable to save

c:websitesuploads” + FileUpload1.FileName +“<br/>” + ex.Message;

   }

  }

  else

  {

   str = “No file uploaded.”;

  }

  lblMessage.Text = str;

  lblDisplay.Text = “”;

 }

 protected void btnDisplay_Click(object sender, EventArgs e)

 {

  string str = “<u>File: “ + FileUpload1.FileName + “</u><br/>”;

  if (FileUpload1.HasFile)

  {

   try

   {

    Stream stream = FileUpload1.FileContent;

    StreamReader reader = new StreamReader(stream);

    string strLine = “”;

    do

    {

     strLine = reader.ReadLine( );

     str += strLine;

    } while (strLine != null);

   }

   catch (Exception ex)

   {

    str += “<br/><b>Error</b><br/>Unable to display “ + FileUpload1.FileName +

“<br/>” + ex.Message;

   }

  }

  else

  {

   str = “No file uploaded.”;

  }

  lblDisplay.Text = str;

  lblMessage.Text = “”;

 }

}

  高亮顯示的using聲明對于不使用完全限定命名空間,而使用Stream對象是必須的。

  在Save按鈕的btnSave_Click事件處理程式中,FileUpload控件的HasFile屬性用于檢測文本框中是否輸入了有效的完全限定檔案名。如果文本框為空或輸入的名稱無效,将不會通過檢測,并且lblMessage将顯示“No file upladed”。

  假定上傳了一個有效檔案,那麼将執行try代碼塊中的代碼。關鍵語句是調用File- Upload控件的SaveAs方法。該方法使用寫死路徑和FileName屬性傳遞一個完全限定的檔案名。該語句可能會由于各種原因而失敗,包括磁盤空間不足、無效的路徑或安全問題(稍後會有更詳細的說明)。

  如果SaveAs方法失敗,則執行catch代碼塊。在lblMessage中顯示一個錯誤資訊,包括該異常的Message屬性ex.Message。

  如果SaveAs方法執行成功,關于上傳檔案的多個資訊将顯示在lblMessage中,這些資訊通過FileUpload.PostedFile(類型為HttpPostedFile)中的屬性擷取。

  Display按鈕的Click事件處理程式與前面的類似,隻不過它不是顯示檔案資訊,而是顯示檔案内容。它通過使用FileContent屬性擷取表現為Stream對象的上傳檔案的内容,然後這個Stream對象被用于執行個體化一個StreamReader對象。StreamReader的Read- Line方法逐行的周遊檔案,然後把合并後的字元串顯示在lblDisplay中。

  當在讨論從用戶端上傳檔案到web伺服器時,安全是非常讓人關注的。須注意兩點,首先,使用這種方式會公開web伺服器,進而會有非常大的安全漏洞,為此要特别細心。因為這樣不僅可以上傳病毒,木馬和其他惡意軟體,還會存在用戶端浏覽web伺服器目

  錄結構的危險。是以,應該使用寫死目标目錄,至少嚴格限定在哪裡儲存上傳的檔案。

  另外,要注意的一點是,允許在磁盤寫檔案所必需的權限。在開發web應用程式時,一般情況下,開發機器同時也是web伺服器,特别是使用VS2005預設的開發模式。在該模式下使用的是内置的web伺服器,并且不通過IIS通路網站而是由檔案系統通路網站。這樣,永遠也不會有權限問題。

  然而,當網站部署到産品伺服器上,且該網站通過IIS和虛拟目錄來通路時,就會出現問題。這是因為運作ASP.NET的賬戶必須擁有對用于儲存上傳檔案的目錄的寫權限。在Windows2000/XP中,賬戶的名稱是ASPNET。在Windows Server2003中,寫權限必須配置設定給IIS_WPG賬戶組。

  利用FileUpload控件并結合良好的安全防護,使用者可以把自己的檔案傳送到網站,以豐富網站功能。

預設情況下,FileUpload控件上傳大小為4096kb,這是用Web.config檔案的<httpRuntime>配置節中的maxRequestLength屬性來設定,如果需要上傳大于4096kb的檔案,則需要修改這這一配置.

檔案上傳大小不能超過記憶體大小的60%.這裡的60%也是web.config檔案的預設配置,<procesModel>配置中的memoryLimit屬性的預設值.雖然可以修改,但是這給伺服器帶來的負擔可想而知.建議不要修改此值.