System.Net.Mail.SmtpClient:SMTP 連線與發送System.Net.Mail.MailMessage:郵件內容、收件人、附件System.Net.Mail.Attachment:附件與內嵌資源System.Net.NetworkCredential:認證資訊<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);
}
}
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);
}
// 例如從 FileUpload 控制項直接取得 Stream
var attachment = new Attachment(fileUpload.PostedFile.InputStream, fileUpload.PostedFile.ContentType)
{
Name = fileUpload.FileName,
ContentDisposition = { Inline = false } // 一般附件
};
msg.Attachments.Add(attachment);
using (var client = new SmtpClient
{
Host = "mail.internal.corp", // 內網 SMTP
Port = 25, // 無加密標準埠
EnableSsl = false,
UseDefaultCredentials = false,
// Credentials = null, // 匿名,不提供認證
DeliveryMethod = SmtpDeliveryMethod.Network
})
{
client.Send(msg);
}
public static Task SendAsync(MailMessage msg)
{
var client = new SmtpClient { /* 設定同上 */ };
var tcs = new TaskCompletionSource
| 錯誤 | 原因 | 解決 |
|---|---|---|
5.7.0 Authentication Required | Gmail/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) |
// 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**,避免踩坑並獲得現代郵件協定完整支援。