GMail 没有显示 inline-images (cid) 我用 System.Net.Mail 发送

GMail not showing inline-images (cid) i'm sending with System.Net.Mail

当我通过 outlook 或 gmail 向 gmail 电子邮件地址发送电子邮件时,我可以添加 inline-images,这直接显示在 gmail 网络界面中:

工作电子邮件的相关原始 mail-header 和原始 body 部分:

--089e0158b6909948880520cef593
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Image there?<div><img src=3D"cid:ii_if3zqhar0_15014363be0a=
41b2" width=3D"10" height=3D"3"><br>=E2=80=8BHope so!<br></div></div>

--089e0158b6909948880520cef593--
--089e0158b69099488c0520cef594
Content-Type: image/png; name="test.png"
Content-Disposition: inline; filename="test.png"
Content-Transfer-Encoding: base64
Content-ID: <ii_if3zqhar0_15014363be0a41b2>
X-Attachment-Id: ii_if3zqhar0_15014363be0a41b2

iVBORw0KGgoAAAANSUhEUgAAAAoAAAADCAIAAAAlXwkiAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ
bWFnZVJlYWR5ccllPAAAADFJREFUeNpi+A8BDCf/wwDD/1VIbBABIudDmAchokwgag9QAiwHVcsM
Z/5fCdYJEGAAuthJ+AVi5KgAAAAASUVORK5CYII=
--089e0158b69099488c0520cef594--

完整的原始电子邮件:Working raw-email

但是,当我通过 System.Net.Mail.NET 发送这样一封电子邮件时,它在 gmail 网络界面中不起作用,但在任何其他电子邮件客户端(outlook、iphone 等)中都不起作用:

non-working 电子邮件的相关原始 mail-header 和 raw-body 部分:

----boundary_3_6a0761ee-57e2-4bdd-b1f1-7302b3c8a7a1
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Image there?<br /><img src=3D"cid:test.png@71236720.91827344" /><=
br />Hope so!
----boundary_3_6a0761ee-57e2-4bdd-b1f1-7302b3c8a7a1--

----boundary_5_979e00c0-3fb9-46a0-b25c-1cee82cc15eb
Content-Type: image/png; name=test.png
Content-Transfer-Encoding: base64
Content-Disposition: inline; filename=test.png
Content-ID: <test.png@71236720.91827344>

iVBORw0KGgoAAAANSUhEUgAAAAoAAAADCAIAAAAlXwkiAAAAGXRFWHRTb2Z0d2FyZQBB
ZG9iZSBJbWFnZVJlYWR5ccllPAAAADFJREFUeNpi+A8BDCf/wwDD/1VIbBABIudDmAch
okwgag9QAiwHVcsMZ/5fCdYJEGAAuthJ+AVi5KgAAAAASUVORK5CYII=
----boundary_5_979e00c0-3fb9-46a0-b25c-1cee82cc15eb--

完整 non-working 原始电子邮件:Nonworking raw-email.

这是我要发送的代码 inline-images:

SmtpClient client = new SmtpClient("real.server.on.the.internet");
MailMessage mail = new MailMessage("Flattiverse <xxx@flattiverse.com>", "Ghostie <xxx@gmail.com>");
mail.BodyEncoding = System.Text.Encoding.UTF8;
mail.SubjectEncoding = System.Text.Encoding.UTF8;

AlternateView plainView = AlternateView.CreateAlternateViewFromString("Please view as HTML-Mail.", System.Text.Encoding.UTF8, "text/plain");
plainView.TransferEncoding = System.Net.Mime.TransferEncoding.QuotedPrintable;

AlternateView htmlView = AlternateView.CreateAlternateViewFromString("Image there?<br /><img src=\"cid:test.png@71236720.91827344\" /><br />Hope so!", System.Text.Encoding.UTF8, "text/html");
htmlView.TransferEncoding = System.Net.Mime.TransferEncoding.QuotedPrintable;
mail.AlternateViews.Add(plainView);
mail.AlternateViews.Add(htmlView);

mail.Subject = "7";

Attachment attachment = new Attachment("test.png", "image/png");
attachment.ContentId = "test.png@71236720.91827344";
attachment.ContentDisposition.Inline = true;
attachment.ContentDisposition.DispositionType = "inline; filename=test.png";
mail.Attachments.Add(attachment);

client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential("working_username", "working_password");
client.Send(mail);

我还尝试了 GMail 格式的 cid(例如 ii_012345678_9abcdef0123456789)以及其他相关问题中所述的许多其他内容。 (在邮件 body 等中使用 ' 而不是 ")

问题:GMail 不显示我的 inline-images,我做错了什么?我需要如何更改我的代码?也许我想要的用System.Net.Mail?

无法实现

当添加为附件时,内联图像在 GMail 网络界面中被忽略。将图像添加为替代视图时,它会被 Outlook 忽略。

要添加与 GMail 网络界面和 Outlook(以及 iPhone 邮件客户端)兼容的内联图像,您必须将其添加为 LinkedResource

问题中的示例代码必须这样固定:

SmtpClient client = new SmtpClient("real.server.on.the.internet");
MailMessage mail = new MailMessage("Flattiverse <info@flattiverse.com>", "Ghostie <matthias.lukaseder.test@gmail.com>");
mail.BodyEncoding = System.Text.Encoding.UTF8;
mail.SubjectEncoding = System.Text.Encoding.UTF8;

LinkedResource image = new LinkedResource("test.png", "image/png");
image.ContentId = "test.png@71236720.91827344";
image.TransferEncoding = System.Net.Mime.TransferEncoding.Base64;
image.ContentType.Name = "test.png@71236720.91827344";
image.ContentLink = new Uri("cid:test.png@71236720.91827344");

AlternateView plainView = AlternateView.CreateAlternateViewFromString("Please view as HTML-Mail.", System.Text.Encoding.UTF8, "text/plain");
plainView.TransferEncoding = System.Net.Mime.TransferEncoding.QuotedPrintable;

AlternateView htmlView = AlternateView.CreateAlternateViewFromString("Image there?<br /><img src=\"cid:test.png@71236720.91827344\" /><br />Hope so!", System.Text.Encoding.UTF8, "text/html");
htmlView.LinkedResources.Add(image);
htmlView.TransferEncoding = System.Net.Mime.TransferEncoding.QuotedPrintable;
mail.AlternateViews.Add(plainView);
mail.AlternateViews.Add(htmlView);

mail.Subject = "15";

client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential("working_username", "working_password");
client.Send(mail);

我在使用 Python (Django) 时遇到了同样的问题。只需添加 X-Attachment-Id header 即可解决:

img.add_header('Content-ID', '<filename.png>')
img.add_header('X-Attachment-Id', 'filename.png')
img.add_header('Content-Disposition', 'inline', filename='filename.png')
message.attach(img)

希望这对某人有所帮助:-)

我遇到了同样的问题(在 Java 中,对于 c# 也是一样的)。 通过在“<”和“>”之间添加 contentId 解决

这个正在处理 Gmail、yahoo 和 Outlook。

将其添加为 LinkedResource

我有一个名为 Confirm_Account_RegistrationInd.html

的模板
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Bienvenido Email de  {6}</title>
</head>

<body>
    <table width="100%" border="0" cellspacing="0" cellpadding="0">
        <tr>
            <td align="center" valign="top" bgcolor="#fff" style="background-color:lightgray;">
                <br>
                <br>
                <table width="600" border="0" cellspacing="0" cellpadding="0" >
                    <tr>
                        <td height="70" align="left" valign="middle"></td>
                    </tr>
                    <tr>
                        <td align="left" valign="top" bgcolor="#564319" style="background-color:#007ebd; font-family:Arial, Helvetica, sans-serif; padding:10px;">
                            <table>
                                <tr>
                                    <td>
                                        "<img id="logo" src="miimg_id" alt="logo" style="height: 60px; border: 3px solid #007ebd; border-radius: 43px;" />";
                                    </td>
                                    <td>
                                        <div style="font-size:36px; color:#ffffff;">
                                            <b>{0}</b>
                                        </div>
                                        <div style="font-size:13px; color:lightcyan;">
                                            <b>{1} : {6}</b>
                                        </div>
                                    </td>
                                    
                                </tr>
                        </table>
                        </td>
                    </tr>
                    <tr>
                        <td align="left" valign="top" bgcolor="#ffffff" style="background-color:#ffffff;">
                            <table width="100%" border="0" cellspacing="0" cellpadding="0">
                                <tr>
                                    <td align="center" valign="middle" style="padding:10px; color:#564319; font-size:28px; font-family:Georgia, 'Times New Roman', Times, serif;">
                                        ¡Felicitaciones! <small>Estás Registrado.</small>
                                    </td>
                                </tr>
                            </table>
                            <table width="95%" border="0" align="center" cellpadding="0" cellspacing="0">
                                
                                <tr>
                                    <td width="100%" style="color:darkslategrey; font-family:Arial, Helvetica, sans-serif; padding:10px;">
                                        <div style="font-size:16px;">
                                            Apreciad@ {2},
                                        </div>
                                        <div style="font-size:12px;text-align: justify;">
                                            Ha sido creada una cuenta en el sitio.
                                            Todo lo que necesitas es hacer clic en el botón en la parte de abajo (Te tomará solamente un momento)
                                            Este correo es para la verificación de la propiedad del correo elctrónico.
                                            <hr>
                                            <center>

                                                <button type="button" title="Confirmar cuenta" style="background: darkgoldenrod">
                                                    <a href="{5}" style="font-size:22px;  padding: 10px; color: #ffffff">
                                                        Confirmar correo ahora
                                                    </a>
                                                </button>

                                            </center>
                                            <hr>
                                        </div>
                                    </td>
                                </tr>
                            </table>
                            
                            <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0" style="margin-bottom:15px;">
                                <tr>
                                    <td align="left" valign="middle" style="padding:15px; font-family:Arial, Helvetica, sans-serif;">
                                        <div style="font-size:20px; color:#564319;">
                                            <b>Por favor manten tus credenciales seguras, para usarlas en el futuro. </b>
                                        </div>
                                        <div style="font-size:16px; color:#525252;">
                                            <b>Correo         :</b> {3}
                                            <br />
                                            <b>Nombre de usuario :</b> {3}
                                            <br />
                                            {7}
                                            <br />
                                        </div>
                                    </td>
                                </tr>
                            </table>
                            <table width="100%" border="0" cellspacing="0" cellpadding="0">
                                <tr>
                                    <td align="center" valign="middle" style="padding:15px; background-color:#007ebd; font-family:Arial, Helvetica, sans-serif;">

                                        <div style="font-size:20px; color:#fff;">
                                            <b>¡Actualiza tus contraseñas continuamente!</b>
                                        </div>
                                        <br>
                                        <div style="font-size:13px; color:aliceblue;">

                                            <br>


                                        </div>
                                    </td>
                                </tr>
                            </table>
                           
                        </td>
                    </tr>
                    
                </table>
                <br>
                <br>
            </td>
        </tr>
    </table>
</body>
</html>

我要展示的图片:

"<img id="logo" src="miimg_id" alt="logo" style="height: 60px; border: 3px solid #007ebd; border-radius: 43px;" />";

你可以显示 src 属性有一个值 miimg_id

在视图中我有值要填充 {}

我有我的方法,在获取数据以填充值后,我将我的视图读取为字符串,称为 ReSendEmailAsync

[HttpPost]
        public async Task<IActionResult> ReSendEmailAsync([FromBody] string id)
        {
            string returnUrl = null;
            returnUrl = returnUrl ?? Url.Content("~/");

            string empleadoNombre = "";
            string attach = "";
            string logoName = "logo_dif.png";


            var user = await _unitOfWork.ApplicationUser.GetFirstOrDefaultAsync(u => u.Id == int.Parse(id), includeProperties: "Empleado");

            if (user == null)
            {
                return Json(new { success = false, message = "Usuario Email" });
            }
            if (user.EmailConfirmed)
            {
                return Json(new { success = true, message = "Cuenta ya fue confirmada" });
            }

            try
            {
                empleadoNombre = user.Empleado.Nombre;
            }
            catch (Exception e)
            {

            }

            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user).ConfigureAwait(true);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            var callbackUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = user.Id, code = code, returnUrl = returnUrl },
                protocol: Request.Scheme);

            //Customizde email
            var PathToFile = _webHostEnvironment.WebRootPath + Path.DirectorySeparatorChar.ToString()
                + "Templates" + Path.DirectorySeparatorChar.ToString()
                + "EmailTemplates" + Path.DirectorySeparatorChar.ToString()
                + "Confirm_Account_RegistrationInd.html";

            var subject = "Confirmar Registro de cuenta";
            string HtmlBody = "";

            using (StreamReader streamReader = System.IO.File.OpenText(PathToFile))
            {
                HtmlBody = streamReader.ReadToEnd();
            }

        //{0} Subject
        //{1} DateTime
        //{2} Name
        //{3} Email
        //{4} Messaje
        //{5} CallBack
        //{6} AppName
        //{7} Pass

                // logo as attach
                var PathToImage = _webHostEnvironment.WebRootPath + Path.DirectorySeparatorChar.ToString()
                + "Templates" + Path.DirectorySeparatorChar.ToString()
                + "EmailTemplates" + Path.DirectorySeparatorChar.ToString()
                + logoName;

                attach = PathToImage;


            string message = $"Por favor confirme su cuenta <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>Clic Aquí</a>.";
            string messageBody = string.Format(HtmlBody,
                subject,
                String.Format("{0:dddd, d MMMM yyyy}", DateTime.Now),
                empleadoNombre,
                user.Email,
                message,
                callbackUrl,
                "Indicadores",
                ""
             );

            try
            {
                MailRequest mailRequest = new MailRequest();

                mailRequest.Body = messageBody;
                mailRequest.ToEmail = user.Email;
                mailRequest.Subject = "Confirmar su correo";
                mailRequest.Attachments = new List<MailAttachment> 
                { new MailAttachment{
                    Name = logoName,
                    Path = attach
                } };

                await _mailService.SendEmailAsync(mailRequest);
            }
            catch(Exception e)
            {
                return Json(new { success = false, message = "Al enviar email" });
            }

            return Json(new { success = true, message = "Operación exitosa" });
        }

在我的classMailService

主要方法是 SendEmailAsync,我将值传递给 MailMessage 对象

但我有另一种方法叫做 Mail_Body 那个 return 一个 AlternateView object

public class MailService : IMailService
    {
        private readonly MailSettings _mailSettings;
        public MailService(IOptions<MailSettings> mailSettings)
        {
            _mailSettings = mailSettings.Value;
        }

        public async Task SendEmailAsync(MailRequest mailRequest)
        {
            MailMessage message = new MailMessage();
            SmtpClient smtp = new SmtpClient();
            message.From = new MailAddress(_mailSettings.UserName);
            message.To.Add(new MailAddress(mailRequest.ToEmail));
            message.Subject = mailRequest.Subject;
            message.BodyEncoding = System.Text.Encoding.UTF8;
            message.SubjectEncoding = System.Text.Encoding.UTF8;
            if (mailRequest.Attachments != null)
            {
                //int i = 0;
                foreach (var attachmentStr in mailRequest.Attachments)
                {
                    message.AlternateViews.Add(Mail_Body(mailRequest.Body, attachmentStr.Path, attachmentStr.Name));

                }
            }
            message.IsBodyHtml = true;
            smtp.Port = _mailSettings.Port;
            smtp.Host = _mailSettings.Host;
            smtp.EnableSsl = _mailSettings.EnableSSL;
            smtp.UseDefaultCredentials = false;
            smtp.Credentials = new NetworkCredential(_mailSettings.UserName, _mailSettings.Password);
            smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
            await smtp.SendMailAsync(message);
        }

        private AlternateView Mail_Body(string strr, string path, string contentId)
        {

            LinkedResource Img = new LinkedResource(path, "image/png");
            Img.ContentId = "logo_img";

            strr = strr.Replace("\"miimg_id\"", "cid:logo_img");

            AlternateView AV =
            AlternateView.CreateAlternateViewFromString(strr, null, MediaTypeNames.Text.Html);
            AV.LinkedResources.Add(Img);
            return AV;
        }
    }

徽标图片名为 logo_dif.png,位于

gmail 中的最终结果: