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

C# .NET Core每日提醒邮件程序嵌入图片显示异常问题

问题描述

我基于C# .NET Core开发了一个每日定时运行的程序,用于向活动注册用户发送提醒邮件。目前邮件的文字、链接等功能正常,但嵌入的图片始终显示为损坏状态。

文件结构

  • Service
    • Email
      • ReminderEmail.cs
  • wwwroot
    • img
      • email-logo.png

当前尝试过的代码

初始HTML(使用本地路径)

string body = @"
<html>
    <body>
        <img src='wwwroot/img/email-logo.png' width=300 height=100 />
        <p style='color: black;'>Just a reminder, the program you are scheduled to attend is starting soon, the details for your group are below. We look forward to working with you.</p>
            
        <p style='color: black;'><strong>FULL HOCKEY EQUIPMENT</strong>, including your hockey stick, is required. Please arrive approximately 30 minutes prior to the program on the first day so we can get you checked in, and you have time to get dressed. Please bring a water bottle with you and set it on the bench during the session.</p>
            
        <p style='color: black;'>If you are interested in our <strong>testing system</strong> or <strong>video analysis</strong>, please see the instructor at your program.<br />
        <a href='https://prostrideskating.com/ProgramEvents/Testing'>Learn More About Testing System</a><br />
        <a href='https://prostrideskating.com/VideoAnalysis'>Learn More About Video Analysis</a></p>

            
        <p><mark><strong>Program</strong><br />
        Set Name: {programSetName}<br />
        Event Start: {formattedStartDate}<br />
        Event End: {formattedEndDate}<br />
        Details: {details}</mark></p>
         
        <p><mark><strong>Location</strong><br />
        {locationName}<br />
        {address}<br />
        {city}, {state} {postalCode}<br />
        {country}</mark></p>
            
        <p style='color: black;'>If for any reason you cannot attend, please refer to our <a href='https://www.prostrideskating.com/Terms'>cancellation policy</a> and contact us prior to the start of the program.</p>

        <hr />

        <p style='color: black;'>Pro Stride Elite Skating<br />
        <a href='www.prostrideskating.com'>www.prostrideskating.com</a><br />
        Office: 508-406-7552<br />
        Email: <a href='mailto:Info@prostrideskating.com'>Info@prostrideskating.com</a></p>
    </body>
</html>";

邮件发送代码

var mail = new MimeMessage();
mail.From.Add(new MailboxAddress("name", username));
mail.To.Add(new MailboxAddress(email, email));
//mail.Cc.Add(new MailboxAddress("name", "email@gmail.com"));
mail.Subject = "Subject";
mail.Body = new TextPart("html")
{
    Text = body
};

尝试Base64嵌入但失败

string imagePath = "wwwroot/img/email-logo.png";

// Read the content of the image file
byte[] imageBytes = System.IO.File.ReadAllBytes(imagePath);

// Convert the byte array to a base64 string
string base64String = Convert.ToBase64String(imageBytes);

//html code
<html>
  <body>
    <img src='data:image/png;base64,base64String' width=100 height=30 />
... rest of code

解决方案

方法1:将图片作为嵌入式资源(推荐,兼容性更好)

邮件客户端无法访问服务器本地路径的资源,更可靠的方式是把图片作为邮件的嵌入式附件,通过Content-ID引用。

修改后的完整代码

// 构建邮件
var mail = new MimeMessage();
mail.From.Add(new MailboxAddress("name", username));
mail.To.Add(new MailboxAddress(email, email));
mail.Subject = "Subject";

// 创建多部分邮件内容
var multipart = new Multipart("related");

// 构建HTML正文,img的src改为cid:email-logo(需和附件的Content-ID一致)
string body = @"
<html>
    <body>
        <img src='cid:email-logo' width=300 height=100 />
        <!-- 剩余HTML内容与之前一致 -->
        <p style='color: black;'>Just a reminder, the program you are scheduled to attend is starting soon, the details for your group are below. We look forward to working with you.</p>
            
        <p style='color: black;'><strong>FULL HOCKEY EQUIPMENT</strong>, including your hockey stick, is required. Please arrive approximately 30 minutes prior to the program on the first day so we can get you checked in, and you have time to get dressed. Please bring a water bottle with you and set it on the bench during the session.</p>
            
        <p style='color: black;'>If you are interested in our <strong>testing system</strong> or <strong>video analysis</strong>, please see the instructor at your program.<br />
        <a href='https://prostrideskating.com/ProgramEvents/Testing'>Learn More About Testing System</a><br />
        <a href='https://prostrideskating.com/VideoAnalysis'>Learn More About Video Analysis</a></p>

            
        <p><mark><strong>Program</strong><br />
        Set Name: {programSetName}<br />
        Event Start: {formattedStartDate}<br />
        Event End: {formattedEndDate}<br />
        Details: {details}</mark></p>
         
        <p><mark><strong>Location</strong><br />
        {locationName}<br />
        {address}<br />
        {city}, {state} {postalCode}<br />
        {country}</mark></p>
            
        <p style='color: black;'>If for any reason you cannot attend, please refer to our <a href='https://www.prostrideskating.com/Terms'>cancellation policy</a> and contact us prior to the start of the program.</p>

        <hr />

        <p style='color: black;'>Pro Stride Elite Skating<br />
        <a href='www.prostrideskating.com'>www.prostrideskating.com</a><br />
        Office: 508-406-7552<br />
        Email: <a href='mailto:Info@prostrideskating.com'>Info@prostrideskating.com</a></p>
    </body>
</html>";

// 添加HTML部分到多内容容器
multipart.Add(new TextPart("html") { Text = body });

// 获取图片绝对路径,避免运行目录差异导致找不到文件
var imagePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "img", "email-logo.png");
var imageBytes = File.ReadAllBytes(imagePath);

// 创建图片附件并标记为嵌入式
var imagePart = new MimePart("image", "png")
{
    Content = new MimeContent(new MemoryStream(imageBytes)),
    ContentId = "email-logo", // 必须与HTML中的cid值完全匹配
    ContentDisposition = new ContentDisposition(ContentDisposition.Inline),
    ContentTransferEncoding = ContentEncoding.Base64
};
multipart.Add(imagePart);

// 设置邮件主体
mail.Body = multipart;

// 发送邮件(补充你的SMTP配置)
using (var client = new SmtpClient())
{
    client.Connect("smtp.your-server.com", 587, SecureSocketOptions.StartTls);
    client.Authenticate(username, password);
    client.Send(mail);
    client.Disconnect(true);
}

方法2:修复Base64嵌入的错误

你之前的Base64写法错误,未将变量base64String的值插入到HTML中,导致邮件显示文本而非图片。

修改后的Base64代码

// 获取图片绝对路径
var imagePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "img", "email-logo.png");
byte[] imageBytes = File.ReadAllBytes(imagePath);
string base64String = Convert.ToBase64String(imageBytes);

// 用字符串插值将Base64值插入HTML
string body = $@"
<html>
    <body>
        <img src='data:image/png;base64,{base64String}' width=300 height=100 />
        <!-- 剩余HTML内容与之前一致 -->
    </body>
</html>";

// 邮件发送代码与之前一致(注意:部分邮件客户端可能屏蔽Base64图片)
var mail = new MimeMessage();
mail.From.Add(new MailboxAddress("name", username));
mail.To.Add(new MailboxAddress(email, email));
mail.Subject = "Subject";
mail.Body = new TextPart("html") { Text = body };

关键注意事项
  1. 本地路径无效:邮件客户端无法访问服务器本地文件路径,必须将图片嵌入邮件或使用公网可访问的URL。
  2. Content-ID匹配:方法1中,HTML里的cid:xxx必须与附件的ContentId完全一致。
  3. 路径拼接:使用Path.Combine和Directory.GetCurrentDirectory()确保获取正确的图片绝对路径,避免因运行目录不同导致文件找不到。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 23:08:12