首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET FileUpload 單檔/多檔上傳完整實作:驗證、儲存、錯誤處理

     編輯:ASP.NET 基礎

單檔上傳基礎版

前端 .aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<html>
<body>
    <form id="form1" runat="server">
        <asp:FileUpload ID="FileUpload1" runat="server" />
        <asp:Button ID="Button1" runat="server" Text="上傳" OnClick="Button1_Click" />
        <asp:Label ID="Label1" runat="server" />
        <!-- 選擇性:客戶端副檔名驗證 -->
        <asp:RegularExpressionValidator ID="Rev1" runat="server" 
            ControlToValidate="FileUpload1" 
            ErrorMessage="僅限 jpg/gif" 
            ValidationExpression="^.*\.(jpg|jpeg|gif|png)$" 
            Display="Dynamic" />
    </form>
</body>
</html>

後端 .aspx.cs

protected void Button1_Click(object sender, EventArgs e)
{
    string savePath = @"F:\Uploads\"; // 生產環境請用 Server.MapPath("~/Uploads/")
    if (FileUpload1.HasFile)
    {
        string fileName = Path.GetFileName(FileUpload1.FileName);
        string fullPath = Path.Combine(savePath, fileName);
        FileUpload1.SaveAs(fullPath);

        Label1.Text = $"類型: {FileUpload1.PostedFile.ContentType}, 大小: {FileUpload1.PostedFile.ContentLength} bytes
" + $""; } else { Label1.Text = "未選擇檔案"; } }

標準化上傳頁面 (含錯誤處理、資訊顯示)

protected void Button1_Click(object sender, EventArgs e)
{
    if (FileUpload1.HasFile)
    {
        try
        {
            string uploadDir = Server.MapPath("~/Uploads/");
            if (!Directory.Exists(uploadDir)) Directory.CreateDirectory(uploadDir);

            string fileName = Path.GetFileName(FileUpload1.FileName);
            string fullPath = Path.Combine(uploadDir, fileName);

            FileUpload1.SaveAs(fullPath);

            Label1.Text = $"客戶端路徑: {FileUpload1.PostedFile.FileName}
" + $"檔名: {fileName}
" + $"副檔名: {Path.GetExtension(fileName)}
" + $"大小: {FileUpload1.PostedFile.ContentLength} KB
" + $"MIME: {FileUpload1.PostedFile.ContentType}
" + $"儲存路徑: {fullPath}"; } catch (Exception ex) { Label1.Text = "發生錯誤: " + ex.Message; } } else { Label1.Text = "沒有選擇要上傳的檔案!"; } }

多檔案上傳 (HttpFileCollection)

單一 `FileUpload` 控制項配合 `AllowMultiple="true"` (ASP.NET 4.5+),或傳統方式透過 `Request.Files` 取得所有檔案。

protected void Button1_Click(object sender, EventArgs e)
{
    string uploadDir = Server.MapPath("~/Uploads/");
    if (!Directory.Exists(uploadDir)) Directory.CreateDirectory(uploadDir);

    HttpFileCollection files = Request.Files; // 取得所有上傳檔案
    for (int i = 0; i < files.Count; i++)
    {
        HttpPostedFile file = files[i];
        try
        {
            if (file.ContentLength > 0)
            {
                string fileName = Path.GetFileName(file.FileName);
                string fullPath = Path.Combine(uploadDir, fileName);
                file.SaveAs(fullPath);

                Label1.Text += $"檔案 #{i+1}: {fileName} ({file.ContentLength} bytes) 上傳成功
"; } } catch (Exception ex) { Label1.Text += $"檔案 #{i+1} 發生錯誤: {ex.Message}
"; } } }

伺服器端副檔名驗證 (必要防禦)

protected void Button1_Click(object sender, EventArgs e)
{
    if (FileUpload1.HasFile)
    {
        string ext = Path.GetExtension(FileUpload1.FileName).ToLowerInvariant();
        string[] allowed = { ".rar", ".zip", ".pdf", ".doc", ".docx" };

        if (Array.Exists(allowed, a => a == ext))
        {
            // 儲存邏輯...
        }
        else
        {
            Label1.Text = "僅允許上傳 .rar, .zip, .pdf, .doc, .docx 檔案!";
        }
    }
}

突破 4MB 預設限制 (Web.config)

<system.web>
  <!-- maxRequestLength: KB, executionTimeout: 秒 -->
  <httpRuntime maxRequestLength="102400" executionTimeout="600" /> <!-- 100 MB, 10 分鐘 -->
</system.web>

<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="104857600" /> <!-- bytes, IIS 7+ -->
    </requestFiltering>
  </security>
</system.webServer>

multipart/form-data 與 Request.Form 共存

ASP.NET 2.0+ **已支援** `enctype="multipart/form-data"` 表單同時讀取 `Request.Form["otherField"]`,無需特殊處理。

protected void Button1_Click(object sender, EventArgs e)
{
    if (FileUpload1.HasFile)
    {
        FileUpload1.SaveAs(...);
        // 直接讀取同表單其他欄位
        string description = Request.Form["txtDescription"]; // 或 txtDescription.Text
        Label1.Text = $"檔案: {FileUpload1.FileName}, 說明: {description}";
    }
}

安全性檢核清單 (部署前必檢)

  1. ✅ **副檔名白名單** 驗證 (伺服器端)
  2. ✅ **Magic Number** 驗證真實檔案類型
  3. ✅ **重新命名** 儲存 (Guid + timestamp + 原副檔名)
  4. ✅ **上傳目錄移除執行權限** (IIS Handler Mappings 移除 *.aspx, *.ashx, *.php 等)
  5. ✅ **maxRequestLength / maxAllowedContentLength** 設定合理上限
  6. ✅ **錯誤訊息不洩露伺服器路徑** (僅顯示友善訊息)
  7. ✅ **大檔案改用分塊上傳** (Plupload/Uppy + WebAPI) 避免記憶體壓力

結語

FileUpload 是 ASP.NET WebForms 內建最簡單的上傳元件,**關鍵在於伺服器端完整驗證 (副檔名+Magic Number)、安全儲存 (重新命名、目錄權限)、Web.config 正確設定大小限制**。多檔案上傳透過 `Request.Files` 或 `AllowMultiple` 即可實現。現代專案若需進度條、分塊、拖曳、預覽,建議前端採用 **Uppy/Plupload/Dropzone** 配合 **ASP.NET Core WebAPI** 實作斷點續傳架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved