更改电子邮件中自动附加文件的名称

Changing name of automatic attached file in e-mail

我正在使用 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 正文,另一个被添加为附件 w/o 一个名称(接收客户端可能会为这部分分配一个随机名称,这就是您所看到的名称)。

或者,您可以完全删除创建 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}", String.Format("cid:{0}", 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);