在 Web 應用程式開發中,將圖片直接儲存於資料庫而非檔案系統,能簡化備份、同步與權限管理。本文將完整示範如何使用 C# ASP.NET 與 SQL Server,建立一套圖片上傳、列表顯示與二進位串流輸出的完整流程,所有程式碼皆可直接複製執行。
於 SQL Server 2000 的 pubs 資料庫中建立 ImageStore 資料表,欄位定義如下:
ImgID (int, 主鍵, Identity)ImageData (image) — 儲存二進位圖片資料ImageContentType (varchar(20)) — MIME 類型,如 image/jpegImageDescription (varchar(200)) — 圖片描述ImageSize (bigint) — 檔案大小 (bytes)頁面包含檔案上傳控制項、描述文字區、上傳按鈕,以及一個 DataGrid 用於顯示已儲存圖片縮圖與中繼資料。關鍵在於 ImageUrl 指向 ReadImage.aspx?id={ImgID},由獨立頁面輸出二進位串流。
<%@ Page Language="c#" Codebehind="processImage.aspx.cs" AutoEventWireup="false" Inherits="imageProcess.imageProcess" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><title>Image Process</title></HEAD>
<body>
<form id="Form1" method="post" runat="server" enctype="multipart/form-data">
<input type="file" id="File1" runat="server" />
<asp:TextBox id="txtDescript" TextMode="MultiLine" runat="server" />
<asp:Button id="btnUpload" Text="上傳" runat="server" />
<asp:DataGrid ID="DG_Persons" AutoGenerateColumns="False" runat="server">
<Columns>
<asp:TemplateColumn HeaderText="圖片編號">
<ItemTemplate><asp:Label Text='<%# Eval("ImgID") %>' runat="server" /></ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="圖片類型">
<ItemTemplate><asp:Label Text='<%# Eval("ImageContentType") %>' runat="server" /></ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="圖片大小">
<ItemTemplate><asp:Label Text='<%# Eval("ImageSize") %>' runat="server" /></ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="照片">
<ItemTemplate>
<asp:Image runat="server" ImageUrl='<%# "ReadImage.aspx?id=" + Eval("ImgID") %>' />
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
</form>
</body></HTML>
核心步驟:
Page_Load 呼叫 dataGridBind() 重新繫結列表。btnUpload_Click 讀取上傳檔案至 byte[],搭配參數化 SQL 指令寫入資料庫,避免 SQL Injection。FormatURL 產生圖片讀取頁面連結。using System;
using System.Data.SqlClient;
using System.IO;
using System.Web.UI.WebControls;
namespace imageProcess
{
public class imageProcess : System.Web.UI.Page
{
protected HtmlInputFile File1;
protected TextBox txtDescript;
protected DataGrid DG_Persons;
protected Button btnUpload;
private void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) dataGridBind();
}
private void dataGridBind()
{
using (SqlConnection con = new SqlConnection("server=.;database=pubs;uid=sa;pwd=;"))
{
con.Open();
SqlCommand cmd = new SqlCommand("SELECT ImgID, ImageContentType, ImageSize FROM ImageStore", con);
DG_Persons.DataSource = cmd.ExecuteReader();
DG_Persons.DataBind();
}
}
private void btnUpload_Click(object sender, EventArgs e)
{
if (File1.PostedFile.ContentLength == 0) return;
byte[] buffer = new byte[File1.PostedFile.ContentLength];
File1.PostedFile.InputStream.Read(buffer, 0, buffer.Length);
using (SqlConnection con = new SqlConnection("server=.;database=pubs;uid=sa;pwd=;"))
{
con.Open();
string sql = @"INSERT INTO ImageStore (ImageData, ImageContentType, ImageDescription, ImageSize)
VALUES (@Image, @Type, @Desc, @Size)";
SqlCommand cmd = new SqlCommand(sql, con);
cmd.Parameters.Add("@Image", System.Data.SqlDbType.Image, buffer.Length).Value = buffer;
cmd.Parameters.Add("@Type", System.Data.SqlDbType.VarChar, 20).Value = File1.PostedFile.ContentType;
cmd.Parameters.Add("@Desc", System.Data.SqlDbType.VarChar, 200).Value = txtDescript.Text;
cmd.Parameters.Add("@Size", System.Data.SqlDbType.BigInt).Value = File1.PostedFile.ContentLength;
cmd.ExecuteNonQuery();
}
dataGridBind();
}
protected string FormatURL(object id) => "ReadImage.aspx?id=" + id.ToString();
}
}
此頁面不輸出任何 HTML,僅依 QueryString id 查詢資料庫,設定 Response.ContentType 並以 Response.BinaryWrite 輸出圖片二進位資料,適合直接作為 <img src="ReadImage.aspx?id=1"> 的來源。
using System;
using System.Data.SqlClient;
using System.Web;
namespace imageProcess
{
public class ReadImage : System.Web.UI.Page
{
private void Page_Load(object sender, EventArgs e)
{
string id = Request.QueryString["id"];
if (string.IsNullOrEmpty(id)) return;
using (SqlConnection conn = new SqlConnection("server=.;database=pubs;uid=sa;pwd=;"))
{
SqlCommand cmd = new SqlCommand("SELECT ImageContentType, ImageData FROM ImageStore WHERE ImgID=@id", conn);
cmd.Parameters.AddWithValue("@id", id);
conn.Open();
SqlDataReader dr = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
if (dr.Read())
{
Response.Clear();
Response.ContentType = dr["ImageContentType"].ToString();
Response.BinaryWrite((byte[])dr["ImageData"]);
}
Response.End();
}
}
}
}
web.config 管理連線字串,並採用最小權限資料庫帳號。ReadImage.aspx 可加入快取標頭 (Response.Cache.SetCacheability(HttpCacheability.Public)) 減少資料庫負載。完整範例已涵蓋從上傳、儲存、列表顯示到二進位輸出的完整循環,可直接套用於專案中並依需求擴充。