資料庫儲存圖片二進位資料 (varbinary(max)) 可確保資料一致性與備份完整性。本文完整說明:圖片轉 Byte[] 存入、上傳頁面處理、Byte[] 轉 Image 物件、建立專用 ASHX 串流輸出供 <img> 標籤直接引用。
public static byte[] ImageToBytes(string imgPath)
{
using (FileStream fs = new FileStream(imgPath, FileMode.Open, FileAccess.Read))
{
byte[] bytes = new byte[fs.Length];
fs.Read(bytes, 0, bytes.Length);
return bytes;
}
}
public static Image BytesToImage(byte[] imgBytes)
{
using (MemoryStream ms = new MemoryStream(imgBytes))
{
return Image.FromStream(ms, false);
}
}
public static bool SaveEmployeePhoto(Employee model, string imgPath)
{
try
{
model.Photo = ImageToBytes(imgPath);
return EmployeeService.SaveEmployeePhoto(model); // 內部 DAL 邏輯
}
catch { throw; }
}
protected void btnUpload_Click(object sender, EventArgs e)
{
string serverPath = Server.MapPath("~/images/");
if (!fuPhoto.HasFile) return;
string fileName = fuPhoto.PostedFile.FileName;
string mime = fuPhoto.PostedFile.ContentType.ToLower();
if (mime.IndexOf("image") < 0) { /* 格式錯誤 */ return; }
if (fuPhoto.PostedFile.ContentLength > 2 * 1024 * 1024) { /* 超過 2MB */ return; }
string savePath = serverPath + DateTime.Now.ToString("yyyyMMddHHmmss") + fileName;
try
{
fuPhoto.PostedFile.SaveAs(savePath); // 先存實體檔
Employee emp = new Employee(int.Parse(hidId.Value));
bool ok = UploadHelper.SaveEmployeePhoto(emp, savePath);
}
finally
{
if (File.Exists(savePath)) File.Delete(savePath); // 清理暫存檔
}
}
WebForm 無法直接將 Image 物件綁定給 <asp:Image>,需透過專用處理常式輸出二進位串流:
<%@ WebHandler Language="C#" Class="ImgHandler" %>
using System;
using System.Web;
using System.IO;
using System.Drawing;
public class ImgHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string empId = context.Request["employeeId"];
if (string.IsNullOrEmpty(empId)) return;
Employee emp = EmployeeService.GetEmployeeById(int.Parse(empId));
if (emp?.Photo == null) return;
context.Response.Buffer = false;
context.Response.ContentType = "image/jpeg";
context.Response.AddHeader("Content-Disposition", "inline;filename=photo.jpg");
context.Response.BinaryWrite(emp.Photo); // 直接寫入二進位串流
context.Response.End();
}
public bool IsReusable { get { return false; } }
}
<asp:Image ID="imgPhoto" runat="server" />
// Page_Load 中:
imgPhoto.ImageUrl = "ImgHandler.ashx?employeeId=" + empId;
| 優勢 | 說明 |
|---|---|
| 資料完整性 | 圖片與主資料同交易、同備份、同遷移 |
| 權限控管 | ImgHandler 可加入 Session/權限檢查,防止圖片外洩 |
| 避免檔案系統管理 | 無需處理檔案命名衝突、目錄權限、跨伺服器同步 |
using 區塊確保串流正確釋放,避免記憶體洩漏