c# 如何发送邮件

来源:这里教程网 时间:2026-02-21 17:36:46 作者:

SmtpClient
发送纯文本邮件最简单

只要 SMTP 服务器地址、端口、账号密码正确,几行代码就能发出去。注意 .NET Core 5+ 已将

SmtpClient
标记为“过时”,但目前仍可正常使用;若用 .NET 6+ 且追求长期维护,建议迁移到第三方库(如
MailKit
),不过对内部通知类小项目,
SmtpClient
足够快、够稳。

关键点:

SmtpClient
默认不启用 SSL/TLS,但现代邮箱(Gmail、Outlook、腾讯企业邮)基本要求
EnableSsl = true
端口不是固定 25:Gmail 用 587(STARTTLS),部分服务器用 465(SSL) 发件人邮箱必须和
Credentials
的用户名一致,否则多数 SMTP 服务会拒信
别把密码硬编码在代码里——用
ConfigurationManager
IConfiguration
读取
var client = new SmtpClient("smtp.qq.com")
{
    Port = 587,
    Credentials = new NetworkCredential("your@qq.com", "your-app-password"),
    EnableSsl = true
};
var mail = new MailMessage
{
    From = new MailAddress("your@qq.com"),
    Subject = "测试邮件",
    Body = "这是一封纯文本邮件",
    IsBodyHtml = false
};
mail.To.Add("target@example.com");
client.Send(mail);

发送 HTML 邮件要设
IsBodyHtml = true
并注意内联样式

HTML 邮件在客户端渲染差异大,

<style></style>
标签和外部 CSS 基本无效,必须用
style="..."
写内联样式。图片尽量用绝对 URL(
https://
开头),避免引用本地路径或相对路径。

常见陷阱:

忘记设
IsBodyHtml = true
→ 邮件正文显示原始 HTML 标签
用了
<div> 或 Flex 布局 → 多数邮箱客户端(尤其是 Outlook)不支持,推荐用老式 <code><table> 布局
<li>字体写 <code>font-family: 'Segoe UI', sans-serif
→ 安全字体只写
Verdana, Arial, Helvetica, sans-serif
mail.Body = "<p style=\"color:#333;font-family:Verdana,Arial,sans-serif\">欢迎<strong>注册</strong>!</p>";
mail.IsBodyHtml = true;

带附件时用
Attachment
类,注意文件流不能被提前释放

附件本质是内存或磁盘上的字节流,添加到

MailMessage.Attachments
后,
SmtpClient.Send()
期间会读取它。如果用
new Attachment(File.OpenRead(...))
,文件流可能在发送前就被 GC 关闭。

稳妥做法:

new Attachment(string fileName)
构造器(自动管理流)
若需动态生成内容(比如导出 Excel),先写入
MemoryStream
,再传给
Attachment
,并确保该流在
Send()
完成前未被
Dispose()
附件名含中文?用
Attachment.NameEncoding = Encoding.UTF8
防止乱码
var attachment = new Attachment(@"C:\report.pdf");
attachment.NameEncoding = Encoding.UTF8;
mail.Attachments.Add(attachment);

SmtpClient.Send()
报错常见原因和快速排查

错误信息往往模糊,比如 “Failure sending mail” 或 “Unable to connect to the remote server”,实际原因可能差很远。

优先检查这几项:

网络连通性:
telnet smtp.qq.com 587
(Windows)或
nc -zv smtp.qq.com 587
(Linux/macOS)看是否能通端口
密码是否为“授权码”而非邮箱登录密码(QQ 邮箱、163 邮箱必须开 POP3/SMTP 并生成专用密码) 防火墙或公司代理是否拦截了出站 SMTP 流量 .NET 版本是否太低(.NET Framework 4.0+ 支持 TLS 1.2,旧版本默认只启 TLS 1.0,而 Gmail 等已禁用)→ 可加
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

真正麻烦的是异步发送失败后没异常抛出——

SmtpClient
SendAsync
在出错时只会触发
SendCompleted
事件,且
e.Error
为 null,得靠日志或调试器捕获真实异常。

相关推荐