在 .NET 應用程式開發中,郵件發送功能幾乎是標準配備。雖然 .NET Framework 內建 System.Net.Mail.SmtpClient 提供基本功能,但在某些特殊場景下(如需要精確控制 SMTP 協議流程、支援特定認證機制、或是在不支援高階 API 的舊版環境中),自行實作底層 SMTP 通訊類別反而更具彈性。本文介紹一個完整的 C# SMTP 郵件發送類別 KSN_Smtp,支援多種認證模式、附件處理、HTML/純文字郵件格式,並內建詳細的錯誤碼對照與日誌記錄功能。
MailMessage 類別負責封裝郵件的所有屬性,包含寄件人、收件人集合、主旨、郵件編碼(GB2312、ASCII、Unicode、UTF8)、郵件格式(HTML/純文字)、附件清單與郵件內容位元組陣列。採用 StringCollection 管理多收件人與多附件,設計直觀易用。
類別定義 SmtpValidateTypes 列舉,支援四種認證方式:
\0username\0password 整體 Base64 編碼KSN_Smtp 以 TcpClient 與 NetworkStream 建立 TCP 連線,手動實作 SMTP 指令交互流程:
.\r\n 結束資料傳輸,發送 QUIT 斷線每個指令發送後皆讀取伺服器回應碼,透過內建 errorCodes 與 rightCodes 字典判斷執行成敗,異常時拋出 ApplicationException 並記錄詳細錯誤訊息。
SendMail 方法根據是否有附件、郵件格式(HTML/文字)動態組裝 MIME 結構:
Content-Type: text/plain + Base64 編碼內文multipart/alternative 邊界分隔,僅包含 HTML 部分multipart/mixed 包含文字內文與多個附件部分multipart/mixed 包含 HTML 內文與附件,附件採用 application/octet-stream + Content-Disposition: attachment所有非 ASCII 內容(主旨、內文、附件檔名)均依指定編碼(預設 GB2312)轉 Base64,確保中文相容性。
郵件資料傳輸階段採用 NetworkStream.BeginWrite 非同步寫入,搭配 asyncCallBack 回呼確認完成。完整通訊過程(指令、回應、錯誤)皆記錄於 logs 字串,支援輸出至指定路徑(LogPath),編碼為 GB2312,便於事後除錯審計。
var smtp = new KSN_Smtp("smtp.example.com", 25)
{
UserID = "user@example.com",
Password = "password",
SmtpValidateType = SmtpValidateTypes.Login,
LogPath = @"C:\Logs\smtp.log"
};
var mail = new MailMessage
{
Sender = "user@example.com",
Subject = "測試郵件",
XMailer = "KSN_Smtp v1.0",
MailEncoding = MailEncodings.UTF8,
MailType = MailTypes.Html,
MailBody = Encoding.UTF8.GetBytes("<h1>Hello World</h1>")
};
mail.Receivers.Add("recipient@example.com");
mail.Attachments.Add(@"C:\Files\report.pdf");
bool success = smtp.SendMail(mail);
if (!success) Console.WriteLine("發送失敗:" + smtp.ErrorMessage);
System.Net.Mail.SmtpClient 或 MailKit 等成熟函式庫,支援 SSL/TLS、OAuth2、DKIM 簽章等企業級功能;本類別未內建 SSL/TLS 支援,若需加密傳輸需自行在 NetworkStream 上層包裝 SslStream。| 類別/列舉 | 用途 |
|---|---|
MailMessage | 郵件資料封裝 |
MailEncodings | 郵件編碼枚舉 |
MailTypes | 郵件格式枚舉 |
SmtpValidateTypes | SMTP 認證模式枚舉 |
KSN_Smtp | 核心發送引擎,含連線、認證、組裝、發送、日誌 |