System.Web.Mail 是 .NET Framework 1.x/2.0 時代的郵件發送 API,雖已標記過時 (Obsolete),但在維護舊專案時仍常見。現代專案請改用 System.Net.Mail.SmtpClient。本文提供兩個版本的完整封裝類別供參考。
using System;
using System.Collections;
using System.Web.Mail;
public class LegacyMailSender
{
public void SendTextMail(string from, string password, string to, string subject,
MailPriority priority, string body, string smtpServer, ArrayList attachments)
{
SendMail(from, password, to, subject, priority, body, smtpServer, attachments, MailFormat.Text);
}
public void SendHtmlMail(string from, string password, string to, string subject,
MailPriority priority, string body, string smtpServer, ArrayList attachments)
{
SendMail(from, password, to, subject, priority, body, smtpServer, attachments, MailFormat.Html);
}
private void SendMail(string from, string password, string to, string subject,
MailPriority priority, string body, string smtpServer,
ArrayList attachments, MailFormat format)
{
MailMessage msg = new MailMessage
{
From = from,
To = to,
Subject = subject,
Priority = priority,
BodyFormat = format,
Body = body
};
// 基本驗證 (CDO 配置)
msg.Fields.Add("https://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "1"); // basic
msg.Fields.Add("https://schemas.microsoft.com/cdo/configuration/sendusername", from.Split('@')[0]);
msg.Fields.Add("https://schemas.microsoft.com/cdo/configuration/sendpassword", password);
msg.Fields.Add("https://schemas.microsoft.com/cdo/configuration/smtpserverport", "25");
foreach (string file in attachments)
if (System.IO.File.Exists(file))
msg.Attachments.Add(new MailAttachment(file));
SmtpMail.SmtpServer = smtpServer;
SmtpMail.Send(msg);
}
}
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Mail;
using System.Threading.Tasks;
public class ModernMailSender
{
private readonly SmtpClient _client;
public ModernMailSender(string host, int port, string user, string password, bool enableSsl = true)
{
_client = new SmtpClient(host, port)
{
Credentials = new NetworkCredential(user, password),
EnableSsl = enableSsl,
DeliveryMethod = SmtpDeliveryMethod.Network,
Timeout = 30000
};
}
public async Task SendAsync(string from, string to, string subject, string body,
bool isHtml, IEnumerable attachmentPaths = null)
{
using (var msg = new MailMessage(from, to, subject, body))
{
msg.IsBodyHtml = isHtml;
msg.Priority = MailPriority.Normal;
if (attachmentPaths != null)
foreach (var path in attachmentPaths)
if (System.IO.File.Exists(path))
msg.Attachments.Add(new Attachment(path));
await _client.SendMailAsync(msg);
}
}
// 同步版本
public void Send(string from, string to, string subject, string body,
bool isHtml, IEnumerable attachmentPaths = null)
{
SendAsync(from, to, subject, body, isHtml, attachmentPaths).GetAwaiter().GetResult();
}
}
// 現代版用法
var sender = new ModernMailSender("smtp.gmail.com", 587, "user@gmail.com", "app-password", true);
sender.Send(
from: "user@gmail.com",
to: "target@example.com",
subject: "測試信件",
body: "<h1>HTML 內容</h1><p>支援中文</p>",
isHtml: true,
attachmentPaths: new[] { @"C:\temp\report.pdf" }
);
| 問題 | 原因與對策 |
|---|---|
| Gmail/Outlook 拒絕登入 | 需開啟「低安全性應用程式存取」或使用「應用程式密碼」/ OAuth 2.0 |
| 附件中文檔名亂碼 | 使用 Attachment(path, MediaTypeNames.Application.Octet) 並手動設定 ContentDisposition.FileName = System.Net.Mime.MimeUtility.Encode(fileName) |
| 大量發送被封鎖 | 加入發送間隔、使用專業郵件服務 (SendGrid, Mailgun, Amazon SES) |
| SSL/TLS 協定錯誤 | .NET 4.7+ 預設支援 TLS 1.2,舊版需 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 |
System.Net.Mail + async/await。AlternateViews)。