如何在ASP .NET Core 7中发送含CSS与图片的HTML邮件
问题描述
我正在用ASP .NET Core 7结合SMTP和MailKit发送带HTML标签的邮件,目前能发送简单HTML邮件,但现在需要发送包含页眉、页脚和Logo图片的HTML邮件。尝试插入相关HTML代码后遇到了错误,想解决以下问题:
- 如何在邮件正文中插入包含CSS和图片的HTML代码?
- 这个错误是我的API代码导致的吗?
- 有没有其他实现方式?
我的.NET邮件服务代码
using MailKit.Net.Smtp; using MailKit.Security; using MimeKit; using MimeKit.Text; namespace AgrarianTradeSystemWebAPI.Services.EmailService { public class EmailService : IEmailService { private readonly IConfiguration _config; public EmailService(IConfiguration config) { _config = config; } public void SendEmail(EmailDto request) { var email = new MimeMessage(); email.From.Add(MailboxAddress.Parse(_config.GetSection("EmailConfig:EmailUsername").Value)); email.To.Add(MailboxAddress.Parse(request.To)); email.Subject = request.Subject; email.Body = new TextPart(TextFormat.Html) { Text = request.Body }; using var smtp = new SmtpClient(); smtp.Connect(_config.GetSection("EmailConfig:EmailHost").Value, 587, SecureSocketOptions.StartTls); smtp.Authenticate(_config.GetSection("EmailConfig:EmailUsername").Value, _config.GetSection("EmailConfig:EmailPassword").Value); smtp.Send(email); smtp.Disconnect(true); } } }
DTO类代码
public class EmailDto { public string To { get; set; } = string.Empty; public string Subject { get; set; } = string.Empty; public string Body { get; set; } = string.Empty; }
React端发送请求代码
try { const response = await axios.post('https://localhost:7144/Auth/register', formData); console.log('Server Response:', response.data); if (response.status === 200) { const emailResponse = await axios.post('https://localhost:7144/api/Email', emaildata); console.log('Email Response:', emailResponse.data); } } catch (error) { console.error('Error:', error.response.data); if(error.response.data === "Email exist"){ alert('Error: Email already exists and you can not register from existing email address'); } }
解决方案
1. 错误原因分析
你遇到的问题核心是:直接用TextPart无法处理内嵌图片资源,且邮件客户端对外部CSS/内嵌样式块的支持有限;另外如果HTML中存在未转义的特殊字符(如引号、换行),也会触发解析错误。
2. 实现带内嵌图片和CSS的HTML邮件
要发送包含Logo和样式的邮件,需要用MultipartRelated构建邮件体,将图片作为内嵌资源嵌入,同时优先使用内联CSS保证兼容性。
修改后的邮件服务代码
using MailKit.Net.Smtp; using MailKit.Security; using MimeKit; using MimeKit.Text; namespace AgrarianTradeSystemWebAPI.Services.EmailService { public class EmailService : IEmailService { private readonly IConfiguration _config; public EmailService(IConfiguration config) { _config = config; } // 改为异步方法,避免阻塞主线程 public async Task SendEmailWithEmbeddedContentAsync(EmailWithEmbeddedContentDto request) { var email = new MimeMessage(); email.From.Add(MailboxAddress.Parse(_config["EmailConfig:EmailUsername"])); email.To.Add(MailboxAddress.Parse(request.To)); email.Subject = request.Subject; // 创建关联容器,存放HTML和内嵌资源 var multipart = new MultipartRelated(); // 添加HTML内容 var htmlPart = new TextPart(TextFormat.Html) { Text = request.HtmlBody }; multipart.Add(htmlPart); // 嵌入Logo图片(需保证服务器有文件读取权限) if (!string.IsNullOrEmpty(request.LogoLocalPath)) { var imagePart = new MimePart("image", "png") { Content = new MimeContent(File.OpenRead(request.LogoLocalPath)), ContentId = "email-logo", // 需与HTML中的src="cid:email-logo"对应 ContentDisposition = new ContentDisposition(ContentDisposition.Inline), ContentTransferEncoding = ContentEncoding.Base64 }; multipart.Add(imagePart); } email.Body = multipart; using var smtp = new SmtpClient(); await smtp.ConnectAsync(_config["EmailConfig:EmailHost"], 587, SecureSocketOptions.StartTls); await smtp.AuthenticateAsync(_config["EmailConfig:EmailUsername"], _config["EmailConfig:EmailPassword"]); await smtp.SendAsync(email); await smtp.DisconnectAsync(true); } } }
对应的DTO类
public class EmailWithEmbeddedContentDto { public string To { get; set; } = string.Empty; public string Subject { get; set; } = string.Empty; public string HtmlBody { get; set; } = string.Empty; public string LogoLocalPath { get; set; } = string.Empty; // Logo在服务器上的本地路径 }
兼容的HTML示例
<!DOCTYPE html> <html> <body> <!-- 用内联样式保证邮件客户端兼容 --> <div style="background-color: #f5f5f5; padding: 15px;"> <img src="cid:email-logo" alt="平台Logo" width="120" height="60"> </div> <div style="padding: 20px;"> <p style="font-size: 16px; color: #333;">您好,欢迎注册我们的平台!</p> </div> <div style="text-align: center; color: #666; font-size: 12px; margin-top: 30px; padding-top: 15px; border-top: 1px solid #eee;"> <p>© 2024 您的平台名称 版权所有</p> </div> </body> </html>
3. 关键注意事项
- 图片引用规则:必须用
cid:前缀关联内嵌图片的ContentId,不能直接用本地路径或相对路径;如果使用公网图片,可直接写完整URL。 - CSS兼容性:90%以上的邮件客户端不支持
<style>块和复杂选择器,务必把样式内联到HTML元素上。 - 特殊字符处理:前端传入HTML时,要转义双引号、换行等特殊字符;后端接收后可通过
HttpUtility.HtmlEncode二次处理。 - 异步优化:将同步方法改为异步,避免占用服务器线程资源。
4. 错误排查方向
如果仍报错,检查以下几点:
- Logo文件路径是否正确,服务器是否有读取权限。
- HTML中的
cid:值是否与代码中设置的ContentId完全一致(大小写敏感)。 - HTML是否存在未闭合标签、语法错误。
- SMTP服务器配置(主机、端口、账号密码)是否正确。
内容的提问来源于stack exchange,提问作者Rashmina Amarasinghe
相关产品推荐
相关产品推荐

