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

ASP.NET 檔案上傳、下載、刪除、列表完整實作指南

     編輯:關於C語言

前端頁面 (Upload.aspx)


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Upload.aspx.cs" Inherits="Demo.Upload" %>
<!DOCTYPE html>
<html>
<body>
    <form id="form1" runat="server" enctype="multipart/form-data">
        <asp:FileUpload ID="fuFile" runat="server" />
        <asp:Button ID="btnUpload" runat="server" Text="上傳" OnClick="btnUpload_Click" />
        <br /><br />
        <asp:ListBox ID="lbFiles" runat="server" Rows="10" Width="300px" AutoPostBack="true" OnSelectedIndexChanged="lbFiles_SelectedIndexChanged" />
        <br />
        <asp:LinkButton ID="lbDownload" runat="server" Text="下載選取檔案" OnClick="lbDownload_Click" Visible="false" />
        <asp:LinkButton ID="lbDelete" runat="server" Text="刪除選取檔案" OnClick="lbDelete_Click" Visible="false" ForeColor="Red" />
        <br /><br />
        <asp:Label ID="lblMsg" runat="server" ForeColor="Green" />
    </form>
</body>
</html>

後端程式碼 (Upload.aspx.cs)


using System;
using System.IO;
using System.Web.UI.WebControls;

namespace Demo
{
    public partial class Upload : System.Web.UI.Page
    {
        private const string UploadFolder = "~/Uploads/";

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack) BindFileList();
        }

        // 1. 繫結檔案列表
        private void BindFileList()
        {
            string physPath = Server.MapPath(UploadFolder);
            if (!Directory.Exists(physPath)) Directory.CreateDirectory(physPath);

            lbFiles.Items.Clear();
            foreach (string file in Directory.GetFiles(physPath))
            {
                lbFiles.Items.Add(new ListItem(Path.GetFileName(file), file));
            }
            UpdateButtonState();
        }

        private void UpdateButtonState()
        {
            bool hasSelection = lbFiles.SelectedIndex >= 0;
            lbDownload.Visible = hasSelection;
            lbDelete.Visible = hasSelection;
        }

        // 2. 上傳
        protected void btnUpload_Click(object sender, EventArgs e)
        {
            if (!fuFile.HasFile)
            {
                lblMsg.Text = "請選擇檔案";
                return;
            }

            try
            {
                string physPath = Server.MapPath(UploadFolder);
                string fileName = Path.GetFileName(fuFile.FileName);
                string savePath = Path.Combine(physPath, fileName);

                // 防止同名覆蓋:可加時間戳或 GUID
                if (File.Exists(savePath))
                {
                    string ext = Path.GetExtension(fileName);
                    string name = Path.GetFileNameWithoutExtension(fileName);
                    fileName = $"{name}_{DateTime.Now:yyyyMMddHHmmss}{ext}";
                    savePath = Path.Combine(physPath, fileName);
                }

                fuFile.SaveAs(savePath);
                lblMsg.Text = $"上傳成功:{fileName}";
                BindFileList();
            }
            catch (Exception ex)
            {
                lblMsg.Text = "上傳失敗:" + ex.Message;
            }
        }

        // 3. 選取檔案事件
        protected void lbFiles_SelectedIndexChanged(object sender, EventArgs e)
        {
            UpdateButtonState();
        }

        // 4. 下載
        protected void lbDownload_Click(object sender, EventArgs e)
        {
            string filePath = lbFiles.SelectedValue;
            if (File.Exists(filePath))
            {
                string fileName = Path.GetFileName(filePath);
                Response.Clear();
                Response.ContentType = "application/octet-stream";
                Response.AddHeader("Content-Disposition", $"attachment; filename=\"{fileName}\"");
                Response.TransmitFile(filePath);
                Response.End();
            }
            else
            {
                lblMsg.Text = "檔案不存在";
                BindFileList();
            }
        }

        // 5. 刪除
        protected void lbDelete_Click(object sender, EventArgs e)
        {
            string filePath = lbFiles.SelectedValue;
            try
            {
                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                    lblMsg.Text = "刪除成功";
                }
                else
                {
                    lblMsg.Text = "檔案已不存在";
                }
            }
            catch (Exception ex)
            {
                lblMsg.Text = "刪除失敗:" + ex.Message;
            }
            BindFileList();
        }
    }
}

關鍵技術點總結

功能核心 API注意事項
上傳FileUpload.SaveAs表單需 enctype="multipart/form-data";httpRuntime maxRequestLength 限制大小 (預設 4MB)
列表Directory.GetFiles搭配 Server.MapPath 轉換虛擬路徑
下載Response.TransmitFile大檔案不佔記憶體;Content-Disposition: attachment 強制下載
刪除File.Delete需處理檔案鎖定、權限不足例外

安全性強化清單

  1. 副檔名白名單:僅允許 .jpg, .pdf, .docx 等,拒絕 .exe, .aspx, .ashx 等可執行類型。
  2. 檔案內容驗證:讀取 Magic Number (檔頭位元組) 確認真實格式,防止偽裝副檔名。
  3. 儲存路徑隔離**:上傳目錄設為 非 Web 可執行目錄** (如 App_Data 或網站根目錄外),防止上傳腳本被執行。
  4. 檔名重命名**:使用 GUID 或時間戳重命名,避免路徑遍歷 (../../../) 與同名覆蓋。
  5. 大小限制**:web.config 設定 <httpRuntime maxRequestLength="10240" /> (單位 KB) 與 <security><requestFiltering><requestLimits maxAllowedContentLength="10485760" /></requestFiltering></security> (IIS 7+,單位 Bytes)。
  6. 權限最小化**:應用程式池身分僅擁有上傳目錄寫入權限,無系統目錄權限。
  7. 病毒掃描**:整合 ClamAV 或 Windows Defender 掃描上傳檔案。

進階擴充建議

  • 非同步上傳:async/await + HttpPostedFileBase.InputStream.CopyToAsync (MVC/Core)。
  • 分塊上傳/斷點續傳:Plupload、FineUploader、Tus 協定。
  • 檔案預覽:圖片縮圖、PDF.js、Office Online Viewer。
  • 雲端儲存:Azure Blob Storage、AWS S3、MinIO,本地僅存暫存。
  • 資料庫記錄:檔案元資料 (原始檔名、儲存路徑、上傳者、時間、大小、雜湊值) 存入 DB,檔案系統僅存實體內容。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved