萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> ASP.NET 程式設計

.NET 發送嵌入圖片的 HTML 郵件:完整實作與兩種常見寫法

核心概念:LinkedResource 與 CID

在 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() 釋放資源。

現代化替代方案

  • MailKit / MimeKit:開源、跨平台、功能更強大 (支援 DKIM、S/MIME、更完整的 MIME 結構),為 .NET Core / 5+ 時代首選。
  • FluentEmail:建構者模式 API,支援 Razor 模板、多種發送提供者 (SendGrid, Mailgun, SMTP 等)。

總結

掌握 AlternateView + LinkedResource + cid: 的組合,即可在 .NET Framework 發送專業級的內嵌圖片 HTML 郵件。注意 ContentId 對應、MIME 類型、路徑解析與資源釋放等細節,能大幅降低郵件顯示異常與資源洩漏風險。

copyright © 萬盛學電腦網 all rights reserved