You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#发送HTML邮件时内嵌base64图片不显示的原因及解决方法

问题原因

该问题确实是主流邮箱服务商的通用安全限制导致:包括Gmail在内的几乎所有商用邮箱,都会默认拦截HTML正文中通过data:image/xxx;base64,格式直接内嵌的图片资源。这类限制主要用于防范超长base64字符串注入恶意代码、隐藏跟踪像素非法收集收件人信息等安全风险,因此哪怕同一段HTML在本地浏览器打开可以正常加载图片,邮件客户端、网页端邮箱都会主动过滤这类内嵌资源,不会自动渲染。
另外你贴的原始代码还有一个配置错误:发件人地址被错误设置成了收件人地址,正常应该填写你用来发信的Gmail账号地址,否则也可能触发邮件服务商的拦截规则。

解决方案

不要直接把base64字符串拼接到img标签的src属性中,使用.NET类库自带的LinkedResource实现标准的邮件内嵌图片方案,这种方式符合邮件MIME规范,所有主流邮箱都能正常识别,不会触发安全拦截。
具体实现逻辑:

  • 将HTML中img标签的src属性替换为cid:自定义内容ID格式的占位符,其中内容ID可以自行定义,保证唯一即可
  • 创建AlternateView对象承载HTML格式的邮件正文
  • 将base64字符串转换为内存流,通过LinkedResource加载图片流,设置和HTML占位符一致的ContentID
  • 将图片资源绑定到HTML视图,再把视图添加到邮件对象的AlternateViews集合中

修正后的可运行代码示例:

using System.Net.Mail;
using System.Net.Mime;
using System.IO;
using System.Text;

public static void SendMail(string sendTo, string base64PngContent, Encoding enCode)
{
    string senderEmail = "mail@gmail.com";
    // 注意:Gmail需开启两步验证后生成应用专用密码,不能直接使用账号登录密码
    string senderPassword = "your_gmail_app_password";
    
    using MailMessage mail = new MailMessage();
    SmtpClient smtpServer = new SmtpClient();
    
    // 修正原代码发件人配置错误
    mail.From = new MailAddress(senderEmail);
    mail.To.Add(sendTo);
    mail.Subject = "邮件主题";
    mail.BodyEncoding = enCode;
    mail.IsBodyHtml = true;

    // HTML正文,img标签通过cid引用内嵌资源
    string htmlBody = "<img src='cid:embedded_png_001' />";
    // 创建HTML格式的邮件替代视图
    AlternateView htmlView = AlternateView.CreateAlternateViewFromString(htmlBody, enCode, MediaTypeNames.Text.Html);
    
    // 加载base64图片为内嵌资源
    byte[] imgBytes = Convert.FromBase64String(base64PngContent);
    using MemoryStream imgStream = new MemoryStream(imgBytes);
    LinkedResource embeddedImg = new LinkedResource(imgStream, "image/png")
    {
        ContentId = "embedded_png_001", // 和HTML中cid后的内容保持一致
        TransferEncoding = TransferEncoding.Base64
    };
    htmlView.LinkedResources.Add(embeddedImg);
    mail.AlternateViews.Add(htmlView);

    // SMTP服务配置
    smtpServer.UseDefaultCredentials = false;
    smtpServer.Credentials = new NetworkCredential(senderEmail, senderPassword);
    smtpServer.EnableSsl = true;
    smtpServer.Port = 587;
    smtpServer.Host = "smtp.gmail.com";
    smtpServer.Send(mail);
}
补充注意事项
  • Gmail从2022年起就已经关闭了“低安全性应用访问”入口,直接使用账号密码登录SMTP会报错,必须先给账号开启两步验证,再生成16位的应用专用密码填入代码的密码字段
  • 如果需要内嵌多张图片,为每个图片资源分配唯一的ContentID,和HTML里的cid一一对应即可
  • 不要将图片作为普通附件添加后尝试引用,这种方式大部分邮箱会直接把图片显示在附件栏,不会内嵌到正文对应位置

内容的提问来源于stack exchange,提问作者Amen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 01:33:20