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

ASP.NET WebForms 圖片上傳實戰:實體儲存 + 資料庫記錄 + 格式驗證完整範例

     編輯:ASP.NET 基礎

功能需求與架構

  • 前端:<asp:FileUpload> + 上傳按鈕 + 即時預覽 <asp:Image>
  • 後端:副檔名白名單驗證 → 實體檔案儲存(Server.MapPath) → 資料庫記錄檔名、類型、相對路徑
  • 資料表:image1 (ID PK, ImageName, ImageType, ImagePath)
上傳介面 資料庫記錄

資料庫建表腳本

CREATE TABLE image1 (
    ID INT IDENTITY(1,1) PRIMARY KEY,
    ImageName VARCHAR(100) NOT NULL,
    ImageType VARCHAR(20) NOT NULL,
    ImagePath VARCHAR(200) NOT NULL
);

前端 .aspx 頁面

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UpWord.aspx.cs" Inherits="Demo.UpWord" %>
<!DOCTYPE html>
<html xmlns="https://www.w3.org/1999/xhtml">
<head runat="server">
    <title>圖片上傳示範</title>
</head>
<body>
    <form id="form1" runat="server" enctype="multipart/form-data">
        <div style="padding:20px;">
            <asp:FileUpload ID="FileUpload1" runat="server" />
            <asp:Button ID="UploadButton" runat="server" Text="上傳圖片" OnClick="UploadButton_Click" CssClass="btn btn-primary" />
            <asp:Label ID="lblMsg" runat="server" ForeColor="Red" />
            <br /><br />
            <asp:Image ID="Image1" runat="server" Height="150px" Width="150px" Visible="false" />
        </div>
    </form>
</body>
</html>

關鍵: enctype="multipart/form-data" 否則 FileUpload.HasFile 永為 false。

後端核心邏輯 (UpWord.aspx.cs)

using System;
using System.IO;
using System.Configuration;
using System.Data.SqlClient;
using System.Web.UI.WebControls;

namespace Demo
{
    public partial class UpWord : System.Web.UI.Page
    {
        private readonly string _connStr = ConfigurationManager.ConnectionStrings["ConnectionStr"].ConnectionString;
        private static readonly string[] AllowedExt = { ".jpg", ".jpeg", ".png", ".gif", ".bmp" };
        private const long MaxBytes = 5 * 1024 * 1024; // 5MB

        protected void UploadButton_Click(object sender, EventArgs e)
        {
            lblMsg.Text = "";
            if (!FileUpload1.HasFile)
            {
                lblMsg.Text = "請選擇要上傳的圖片";
                return;
            }

            string ext = Path.GetExtension(FileUpload1.FileName).ToLowerInvariant();
            if (Array.IndexOf(AllowedExt, ext) == -1)
            {
                lblMsg.Text = "僅允許上傳 JPG/PNG/GIF/BMP 格式";
                return;
            }

            if (FileUpload1.PostedFile.ContentLength > MaxBytes)
            {
                lblMsg.Text = "檔案大小不可超過 5MB";
                return;
            }

            try
            {
                // 1. 產生唯一檔名:yyyyMMddHHmmss_ffff + 副檔名
                string fileName = $"{DateTime.Now:yyyyMMddHHmmss_ffff}{ext}";
                string saveDir = Server.MapPath("~/Uploads/");
                if (!Directory.Exists(saveDir)) Directory.CreateDirectory(saveDir);
                string fullPath = Path.Combine(saveDir, fileName);

                // 2. 儲存實體檔案
                FileUpload1.PostedFile.SaveAs(fullPath);

                // 3. 寫入資料庫(參數化)
                const string sql = "INSERT INTO image1 (ImageName, ImageType, ImagePath) VALUES (@name, @type, @path)";
                using (var conn = new SqlConnection(_connStr))
                using (var cmd = new SqlCommand(sql, conn))
                {
                    cmd.Parameters.AddWithValue("@name", Path.GetFileNameWithoutExtension(fileName));
                    cmd.Parameters.AddWithValue("@type", ext);
                    cmd.Parameters.AddWithValue("@path", $"~/Uploads/{fileName}"); // 相對路徑
                    conn.Open();
                    cmd.ExecuteNonQuery();
                }

                // 4. 前端預覽
                Image1.ImageUrl = $"~/Uploads/{fileName}";
                Image1.Visible = true;
                lblMsg.Text = "上傳成功";
                lblMsg.ForeColor = System.Drawing.Color.Green;
            }
            catch (Exception ex)
            {
                // 實際專案請記錄至 Log 系統
                lblMsg.Text = $"上傳失敗:{ex.Message}";
                lblMsg.ForeColor = System.Drawing.Color.Red;
            }
        }
    }
}

安全與最佳實踐補強

風險對策
惡意腳本偽裝圖片上傳1. 僅驗證副檔名不足;2. 讀取檔頭 Magic Number 驗證真實格式;3. 儲存目錄設定 IIS「執行權限 = 無」
檔名衝突覆蓋時間戳 + GUID 雙重保險:$"{DateTime.Now:yyyyMMddHHmmss}_{Guid.NewGuid():N}{ext}"
大檔案導致請求逾時web.config:<httpRuntime maxRequestLength="102400" executionTimeout="300" />(100MB/5分)
路徑遍歷攻擊Path.GetFileName 只取檔名部分;不使用使用者輸入路徑

進階:多檔案上傳 (HTML5 multiple)

<asp:FileUpload ID="FileUpload1" runat="server" AllowMultiple="true" /> // .NET 4.5+
// 後端迴圈 Request.Files 集合處理

總結

本範例示範從前端驗證、實體儲存、資料庫記錄到安全防護的完整上傳鏈路。生產環境建議:

  1. 引入圖片處理庫 進行壓縮/縮圖/水印
  2. 檔案儲存至物件存儲,資料庫僅存 Object Key
  3. 上傳記錄表加上 UploadUserId、UploadTime、FileSize、MD5 供審計與去重
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved