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

.NET SmtpClient 發送郵件完整指南:基本寄送、HTML 內容、附件、內嵌圖片、SSL/TLS、匿名轉發

     編輯:ASP.NET 基礎

核心類別

  • System.Net.Mail.SmtpClient:SMTP 連線與發送
  • System.Net.Mail.MailMessage:郵件內容、收件人、附件
  • System.Net.Mail.Attachment:附件與內嵌資源
  • System.Net.NetworkCredential:認證資訊

1. 基本文字郵件 (Web.config 組態)

<configuration>
  <appSettings>
    <add key="SmtpHost" value="smtp.gmail.com" />
    <add key="SmtpPort" value="587" />
    <add key="SmtpUser" value="your@gmail.com" />
    <add key="SmtpPass" value="app-password" /> <!-- Gmail 需應用程式密碼 -->
    <add key="EnableSsl" value="true" />
  </appSettings>
</configuration>
public static void SendText(string to, string subject, string body)
{
    var msg = new MailMessage
    {
        From = new MailAddress(ConfigurationManager.AppSettings["SmtpUser"]),
        Subject = subject,
        Body = body,
        IsBodyHtml = false
    };
    msg.To.Add(to);
    Send(msg);
}

private static void Send(MailMessage msg)
{
    using (var client = new SmtpClient
    {
        Host = ConfigurationManager.AppSettings["SmtpHost"],
        Port = int.Parse(ConfigurationManager.AppSettings["SmtpPort"]),
        EnableSsl = bool.Parse(ConfigurationManager.AppSettings["EnableSsl"]),
        Credentials = new NetworkCredential(
            ConfigurationManager.AppSettings["SmtpUser"],
            ConfigurationManager.AppSettings["SmtpPass"]),
        DeliveryMethod = SmtpDeliveryMethod.Network
    })
    {
        client.Send(msg);
    }
}

2. HTML 郵件 + 附件 + 內嵌圖片 (Inline)

public static void SendHtmlWithAttachments(string to, string subject, string htmlBody, 
    IEnumerable attachmentPaths = null, 
    Dictionary inlineImages = null) // key=ContentId, value=檔案路徑
{
    var msg = new MailMessage
    {
        From = new MailAddress("sender@example.com"),
        Subject = subject,
        Body = htmlBody,
        IsBodyHtml = true
    };
    msg.To.Add(to);

    // 一般附件
    if (attachmentPaths != null)
    {
        foreach (var path in attachmentPaths)
            msg.Attachments.Add(new Attachment(path));
    }

    // 內嵌圖片:HTML 中用 
    if (inlineImages != null)
    {
        foreach (var kvp in inlineImages)
        {
            var inline = new Attachment(kvp.Value)
            {
                ContentId = kvp.Key,
                ContentDisposition = { Inline = true, DispositionType = DispositionTypeNames.Inline }
            };
            msg.Attachments.Add(inline);
        }
    }

    Send(msg);
}

3. 使用 Stream 當附件來源 (不落地檔案)

// 例如從 FileUpload 控制項直接取得 Stream
var attachment = new Attachment(fileUpload.PostedFile.InputStream, fileUpload.PostedFile.ContentType)
{
    Name = fileUpload.FileName,
    ContentDisposition = { Inline = false } // 一般附件
};
msg.Attachments.Add(attachment);

4. 匿名/開放轉發伺服器 (內網常見)

using (var client = new SmtpClient
{
    Host = "mail.internal.corp", // 內網 SMTP
    Port = 25,                   // 無加密標準埠
    EnableSsl = false,
    UseDefaultCredentials = false,
    // Credentials = null,       // 匿名,不提供認證
    DeliveryMethod = SmtpDeliveryMethod.Network
})
{
    client.Send(msg);
}

5. 非同步發送 + 進度/完成事件 (WinForms/WPF/Console)

public static Task SendAsync(MailMessage msg)
{
    var client = new SmtpClient { /* 設定同上 */ };
    var tcs = new TaskCompletionSource();
    client.SendCompleted += (s, e) =>
    {
        if (e.Error != null) tcs.SetException(e.Error);
        else if (e.Cancelled) tcs.SetCanceled();
        else tcs.SetResult(null);
        client.Dispose();
    };
    client.SendAsync(msg, null);
    return tcs.Task;
}


常見問題排查表

錯誤原因解決
5.7.0 Authentication RequiredGmail/Outlook 禁止低安全性應用程式啟用 2FA → 產生「應用程式密碼」填入 SmtpPass
SSL/TLS 協商失敗Port 465 需 Implicit SSL,SmtpClient 僅支援 Explicit SSL (STARTTLS)改用 Port 587 + EnableSsl=true,或改用 MailKit
中文附件檔名亂碼RFC 2231 編碼問題`attachment.Name = MimeUtility.EncodeText(filename)` (需 MailKit/MimeKit)
大量寄送被封鎖IP 信譽、SPF/DKIM/DMARC 未設定使用專業郵件服務 (SendGrid, Mailgun, Amazon SES)

現代替代方案:MailKit (強烈推薦)

// NuGet: MailKit
using MailKit.Net.Smtp;
using MimeKit;

var message = new MimeMessage();
message.From.Add(new MailboxAddress("Sender", "sender@example.com"));
message.To.Add(new MailboxAddress("Recipient", "to@example.com"));
message.Subject = "Subject";
message.Body = new TextPart("html") { Text = "HTML Body" };

using (var client = new SmtpClient())
{
    client.Connect("smtp.gmail.com", 587, MailKit.Security.SecureSocketOptions.StartTls);
    client.Authenticate("user", "app-password");
    client.Send(message);
    client.Disconnect(true);
}

優點:完整支援 Implicit SSL (Port 465)、OAuth2、DKIM 簽章、國際化檔名、非同步 API、.NET Core/5+/Linux 完美相容。`SmtpClient` 已標記 `` (僅保留相容性)。

小結

`System.Net.Mail` 足以應付簡單發信需求,但遭遇 SSL 模式、國際化檔名、OAuth2、高效能併發發送時,**請直接改用 MailKit**,避免踩坑並獲得現代郵件協定完整支援。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved