问题描述
我正在使用 Mailkit 库发送电子邮件。这是这样做的代码:
public async Task SendAsync(IdentityMessage message)
{
if (message == null)
return;
LinkedResource inline = new LinkedResource(System.Web.Hosting.HostingEnvironment.MapPath($"~/Images/logo.png"))
{
ContentId = Guid.NewGuid().ToString(),ContentType = new ContentType("image/png")
{
Name = "logo.png"
}
};
var htmlBody = message.Body.Replace("{CID:logo}",String.Format("cid:{0}",inline.ContentId));
AlternateView avHtml = AlternateView.CreatealternateViewFromString(htmlBody,null,MediaTypeNames.Text.Html);
avHtml.LinkedResources.Add(inline);
using (MailMessage objMailMsg = new MailMessage())
{
objMailMsg.AlternateViews.Add(avHtml);
objMailMsg.Body = htmlBody;
objMailMsg.Subject = message.Subject;
objMailMsg.BodyEncoding = Encoding.UTF8;
Properties.Settings.Default.Reload();
string fromEmail = Properties.Settings.Default.FromMail;
string fromName = Properties.Settings.Default.FromName;
string smtpPassword = Properties.Settings.Default.PwdSmtp;
objMailMsg.From = new MailAddress(fromEmail,fromName);
objMailMsg.To.Add(message.Destination);
objMailMsg.IsBodyHtml = true;
MimeMessage mime = MimeMessage.CreateFromMailMessage(objMailMsg);
HeaderId[] headersToSign = new HeaderId[] { HeaderId.From,HeaderId.Subject,HeaderId.Date };
string domain = "example.cl";
string selector = "default";
Dkimsigner signer = new Dkimsigner(@"C:\inetpub\dkim.pem",domain,selector)
{
HeaderCanonicalizationAlgorithm = DkimCanonicalizationAlgorithm.Relaxed,BodyCanonicalizationAlgorithm = DkimCanonicalizationAlgorithm.Simple,AgentOrUserIdentifier = "@contact.example.cl",QueryMethod = "dns/txt",};
mime.Prepare(EncodingConstraint.EightBit);
signer.Sign(mime,headersToSign);
using (SmtpClient smtpClient = new SmtpClient())
{
await Task.Run(() =>
{
try
{
smtpClient.Connect(Properties.Settings.Default.ServidorSmtp,Properties.Settings.Default.PuertoSmtp,Properties.Settings.Default.SSLSmtp);
smtpClient.Authenticate(fromEmail,smtpPassword);
smtpClient.Send(mime);
smtpClient.disconnect(true);
}
catch (Exception ex)
{
ErrorLog.Save(ex);
//InfoLog.Save(htmlBody);
}
});
}
}
}
好吧.. 当电子邮件到达时,电子邮件客户端以 HTML 格式正确显示它。但是,电子邮件中还附加了一个 HTML 文件。
该文件被命名为,例如,Attached data without title 00391.html
。如果我在浏览器中打开该文件,则会显示电子邮件正文。
有人知道吗?
解决方法
问题大概是这样的:
var htmlBody = message.Body.Replace("{CID:LOGO}",String.Format("cid:{0}",inline.ContentId));
AlternateView avHtml = AlternateView.CreateAlternateViewFromString(htmlBody,null,MediaTypeNames.Text.Html);
// ...
objMailMsg.AlternateViews.Add(avHtml);
objMailMsg.Body = htmlBody;
您将 HTML 正文文本设置为 2 个不同的正文部分。如果您创建 avHtml
部分,则不需要设置 objMailMsg.Body = htmlBody
。
当 MailKit 稍后将 System.Net.Mail.MailMessage 转换为 MimeMessage 时,它可能会以 2 个重复的部分结束,一个用作实际的 HTML 正文,另一个作为附件添加(不包含名称)(接收客户端可能会为这部分分配一个随机名称,这就是您所看到的)。
或者,您可以完全删除创建 System.Net.Mail.MailMessage 的逻辑,只构建 MimeMessage 并避免转换中的潜在问题。
var bodyBuilder = new BodyBuilder ();
var logo = bodyBuilder.LinkedResources.Add (System.Web.Hosting.HostingEnvironment.MapPath($"~/Images/logo.png"));
var htmlBody = message.Body.Replace("{CID:LOGO}",logo.ContentId));
bodyBuilder.HtmlBody = htmlBody;
Properties.Settings.Default.Reload();
string fromEmail = Properties.Settings.Default.FromMail;
string fromName = Properties.Settings.Default.FromName;
string smtpPassword = Properties.Settings.Default.PwdSmtp;
var mime = new MimeMessage ();
mime.From.Add (new MailboxAddress (fromName,fromEmail));
mime.To.Add (MailboxAddress.Parse (message.Destination));
mime.Subject = message.Subject;
mime.Body = bodyBuilder.ToMessageBody ();
HeaderId[] headersToSign = new HeaderId[] { HeaderId.From,HeaderId.Subject,HeaderId.Date };
string domain = "example.cl";
string selector = "default";
DkimSigner signer = new DkimSigner(@"C:\inetpub\dkim.pem",domain,selector)
{
HeaderCanonicalizationAlgorithm = DkimCanonicalizationAlgorithm.Relaxed,BodyCanonicalizationAlgorithm = DkimCanonicalizationAlgorithm.Simple,AgentOrUserIdentifier = "@contact.example.cl",QueryMethod = "dns/txt",};
mime.Prepare(EncodingConstraint.EightBit);
signer.Sign(mime,headersToSign);