c# 如何发送邮件

14次阅读

SmtpClient 发送邮件需配置正确服务器、端口、凭据并启用 ssl/TLS;.NET Core 5+ 已过时但可用,推荐 mailKit;html 邮件须设 IsBodyHtml=true、用内联样式和 table 布局;附件需注意流生命周期和中文名编码;排查错误优先检查网络、授权码、TLS 版本。

c# 如何发送邮件

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 服务会拒信
  • 别把密码硬编码在代码里——用 ConfigurationManagerIConfiguration 读取
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 邮件在客户端渲染差异大,

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

常见陷阱:

  • 忘记设 IsBodyHtml = true → 邮件正文显示原始 HTML 标签
  • 用了
    flex 布局 → 多数邮箱客户端(尤其是 Outlook)不支持,推荐用老式

    布局

  • 字体写 font-family: 'Segoe ui', sans-serif → 安全字体只写 Verdana, Arial, Helvetica, sans-serif
  • mail.Body = "

    欢迎注册

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

    真正麻烦的是异步发送失败后没异常抛出——SmtpClientSendAsync 在出错时只会触发 SendCompleted 事件,且 e.ErrorNULL,得靠日志或调试器捕获真实异常。

text=ZqhQzanResources