在 HTML 郵件中嵌入圖片,關鍵在於使用 AlternateView 建立 HTML 視圖,並透過 LinkedResource 將圖片檔案以 Content-ID (CID) 方式內嵌。HTML 內容中以 <img src="cid:YourContentId"> 參考該圖片,郵件用戶端解析時會自動替換為內嵌二進位資料,避免外部連結被封鎖或圖片遺失。
using System.Net.Mail;
public void SendMailWithEmbeddedImage()
{
var mail = new MailMessage();
mail.From = new MailAddress("sender@example.com", "發送者名稱");
mail.To.Add("recipient@example.com");
mail.Subject = "測試嵌入圖片郵件";
// 建立 HTML 視圖
string htmlBody = @"內嵌圖片測試
這是一張內嵌圖片:
";
var htmlView = AlternateView.CreateAlternateViewFromString(htmlBody, null, "text/html");
// 讀取圖片檔案並設定 ContentId
var imgResource = new LinkedResource("a.jpg", "image/jpeg"); // 注意 MIME 類型
imgResource.ContentId = "Email001"; // 對應 HTML 中的 cid:Email001
htmlView.LinkedResources.Add(imgResource);
mail.AlternateViews.Add(htmlView);
// 發送
using (var smtp = new SmtpClient("smtp.example.com", 587))
{
smtp.Credentials = new System.Net.NetworkCredential("user", "password");
smtp.EnableSsl = true;
smtp.Send(mail);
}
}
public void SendRichMailAsync()
{
var smtp = new SmtpClient("smtp.163.com")
{
DeliveryMethod = SmtpDeliveryMethod.Network,
Credentials = new NetworkCredential("renzhijie1111", "password"),
EnableSsl = true // 163 SMTP 需 SSL
};
var mail = new MailMessage
{
From = new MailAddress("renzhijie1111@163.com", "無敵任志傑測試"),
Subject = "發送帶圖片郵件",
Priority = MailPriority.Normal
};
mail.To.Add("renzhijie1990@vip.qq.com");
mail.ReplyToList.Add(new MailAddress("renzhijie1111@163.com", "我自己"));
// 1. 純文字備份視圖 (不支援 HTML 的用戶端顯示)
string plainText = "若您看到此內容,表示郵件用戶端不支援 HTML 格式。";
mail.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(plainText, null, "text/plain"));
// 2. HTML 視圖 + 內嵌圖片
string htmlContent = @"這是 HTML 格式郵件<br><br>
VA娛樂網
![]()
";
var htmlView = AlternateView.CreateAlternateViewFromString(htmlContent, null, "text/html");
var logoResource = new LinkedResource(@"d:\1.jpg", "image/jpeg");
logoResource.ContentId = "weblogo"; // 對應 cid:weblogo
htmlView.LinkedResources.Add(logoResource);
mail.AlternateViews.Add(htmlView);
// 3. 進階郵件標頭
mail.Headers.Add("Disposition-Notification-To", "renzhijie1111@163.com"); // 要求閱讀回執
mail.Headers.Add("X-Website", "https://www.jb51.net/"); // 自訂標頭
mail.Headers.Add("ReturnReceipt", "1"); // Lotus Domino 回執
mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure; // 失敗通知
// 4. 非同步發送與完成事件
smtp.SendCompleted += (s, e) =>
{
if (e.Error != null)
Console.WriteLine($"發送失敗: {e.Error.Message}");
else if (e.Cancelled)
Console.WriteLine("發送取消");
else
Console.WriteLine("發送成功");
mail.Dispose();
smtp.Dispose();
};
smtp.SendAsync(mail, null); // 第二參數可傳遞用戶狀態物件
}
| 項目 | 說明 |
|---|---|
| ContentId 唯一性 | 同一封郵件中每個 LinkedResource 的 ContentId 必須唯一,且 HTML 中 cid: 參考名稱需完全一致 (區分大小寫)。 |
| MIME 類型正確性 | new LinkedResource("file.jpg", "image/jpeg") 第二參數需符合實際檔案格式,錯誤會導致部分用戶端無法顯示。 |
| 檔案路徑 | 伺服器端絕對路徑 (如 @"d:\1.jpg") 或相對路徑 (相對於執行目錄);Web 專案常用 Server.MapPath("~/Images/logo.jpg")。 |
| AlternateViews 順序 | 建議先加純文字 text/plain,再加 HTML text/html,符合 RFC 2046 「由簡單到複雜」原則。 |
| 非同步發送 | SendAsync 不會阻塞主執行緒,適合 Web 應用;完成事件中務必 Dispose() 釋放資源。 |
掌握 AlternateView + LinkedResource + cid: 的組合,即可在 .NET Framework 發送專業級的內嵌圖片 HTML 郵件。注意 ContentId 對應、MIME 類型、路徑解析與資源釋放等細節,能大幅降低郵件顯示異常與資源洩漏風險。