根本原因是smtp服务器配置不匹配,尤其.net 6+禁用明文传输后,需按端口选enablessl:587配false(starttls),465配true(ssl/tls);gmail需应用专用密码并开启两步验证;from与credentials需符合服务商校验规则;附件中文名须按rfc 2231编码。

SmtpClient 发送邮件时连接超时或被拒绝
根本原因通常是 SMTP 服务器地址、端口或认证方式不匹配,尤其在 .NET 6+ 默认禁用不安全的明文传输后更常见。很多教程还在用 EnableSsl = true 配 Port = 25,这基本必失败。
-
Port = 587是现代主流(STARTTLS),必须配EnableSsl = false,然后调用SendAsync前会自动升级加密 -
Port = 465是 SSL/TLS 直连,此时要设EnableSsl = true,但部分邮件服务商(如 Outlook)已弃用该端口 - Gmail 要求开启“应用专用密码”,且账号需启用两步验证;国内企业邮箱常需白名单 IP 或绑定域名
- 本地开发用
localhost:25测试?别试了——Windows 自带 SMTP 服务早被移除,Docker 里跑mailhog或直接连真实服务商更靠谱
MailMessage.From 和 SmtpClient.Credentials 不一致导致 530 错误
SmtpClient 认证只看 Credentials,和 MailMessage.From 地址完全无关。但某些服务商(如腾讯企业邮)会校验两者是否同域,否则拒收或进垃圾箱。
-
From必须是已验证过的发信邮箱,不能填test@xxx.com却用admin@yyy.com的凭据登录 -
Credentials推荐用new NetworkCredential("user@domain.com", "app-password"),别用DefaultCredentials(Windows 登录凭据) - QQ 邮箱要求
From和登录账号完全一致;阿里云企业邮允许设置“发信别名”,但需后台开通
.NET 6+ 中 SmtpClient 已过时但没替代方案
微软在 .NET Core 2.0 就标记 SmtpClient 为 Obsolete,.NET 6 起警告升级,但至今没提供官方新 API。硬切第三方库(如 MailKit)不是不行,但得重写认证、附件、编码逻辑。
- 继续用
SmtpClient没问题,只是编译有警告;若项目需长期维护,建议封装一层,把SmtpClient实例创建、配置、发送全包进去,方便未来替换 -
MailKit的SmtpClient.Connect默认不验证证书,开发环境容易忽略RemoteCertificateValidationCallback导致上线报错 - 别在循环里反复 new
SmtpClient——它内部没做连接池,高频发送时用完记得Dispose,否则可能耗尽 socket
附件中文名乱码或收不到
根本问题是 MIME 头里的 filename 参数没按 RFC 2231 编码。Attachment 构造函数传入的字符串不会自动编码,靠系统默认编码(通常是 GBK)写进头里,Outlook 和 Gmail 都会解析失败。
- 手动构造
ContentType:先 newContentType("application/octet-stream"),再设Parameters["name"] = "=?UTF-8?B?" + Convert.ToBase64String(Encoding.UTF8.GetBytes("报告.pdf")) + "?=" - 更简单的方法:用
Attachment.CreateAttachmentFromString 或 <code>new Attachment(stream, contentType),然后单独改ContentDisposition.FileName字段 - 测试时别只看 QQ 邮箱——它对乱码容忍高;务必用 Gmail 和 Outlook Web 同时收件确认
SmtpClient 配置,在 Gmail 上通,在企业微信邮里 535,在阿里云上又变成 452,这种差异没法靠查文档穷举,只能实测+日志抓包。最省事的方式是:把 SmtpClient.EnableSsl、Port、Credentials、From 四个值做成配置项,每次换服务商只调这四个。











