【问题标题】:GMail not showing inline-images (cid) i'm sending with System.Net.MailGMail 未显示我使用 System.Net.Mail 发送的内联图像 (cid)
【发布时间】:2015-12-25 20:38:01
【问题描述】:

当我通过 Outlook 或 gmail 向 gmail 电子邮件地址发送电子邮件时,我可以添加直接显示在 gmail 网络界面中的内联图像:

工作电子邮件的相关原始邮件标题和原始正文部分:

--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

但是,当我从.NET 通过System.Net.Mail 发送此类电子邮件时,它无法在 gmail 网络界面中运行,而是在任何其他电子邮件客户端(outlook、iphone 等)中运行:

非工作电子邮件的相关原始邮件标题和原始正文部分:

----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--

完整的非工作原始电子邮件:Nonworking raw-email

这是我发送内联图像的代码:

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)以及其他相关问题中所述的许多其他内容。 (在邮件正文等中使用 ' 而不是 ")

问题:GMail 不显示我的内联图像,我做错了什么?我需要如何更改我的代码?也许我想要的无法通过System.Net.Mail 实现?

【问题讨论】:

  • 它是否适用于其他电子邮件客户端?
  • 它适用于 iPhone 邮件客户端和问题中提到的 Outlook。此外,它还可以在 gmx webmailer 中使用。
  • 据我所知,我使用备用视图而不是附件创建了内联图像。
  • @CSharper 谢谢。这会在 GMail 中显示图像,但不会在 Outlook 中显示。我会看看每个邮件客户端的正确解决方案是什么,然后回答我自己的问题。如果您愿意,您还可以使用普通邮件客户端和 GMail 的解决方案来回答它,如果您想要声誉积分,我可以批准您的回答。
  • @Matthias :“常规邮件客户端的解决方案......”?内嵌图像的 SMTP 标准中没有任何机制——所有这些方法都是由各种客户端编写者发明的临时扩展,这是您遇到问题中描述的问题的原因之一。

标签: c# .net gmail system.net.mail inline-images


【解决方案1】:

当添加为附件时,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);

【讨论】:

  • 现在对你有用吗?我一直工作到去年 10 月,但突然停止了。
  • 这段代码至少对我有用。您可以尝试在这里注册:www.flattiverse.com。如果它向您发送电子邮件,它仍然有效。如果不是,或者如果图像没有显示它可能不再工作了。
  • 如何使用 ImapGmail API 从 Gmail 下载图片?跨度>
  • 这是题外话,因此我不明白你的问题。我使用了 GMail 网页、IMAP 和 GMail API。但是,图像的显示方式由实现 IMAP 或 GMail API 的应用程序控制。
  • stackoverflow 上最被低估的答案。谢谢大佬。
【解决方案2】:

我对 Pyhon (Django) 也有同样的问题。只需添加 X-Attachment-Id 标头即可解决:

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)

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

【讨论】:

    【解决方案3】:

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

    这个是在 Gmail、yahoo 和 Outlook 上工作的。

    【讨论】:

    • 谢谢,在我已经厌倦了在 gmail 网络界面中显示内联图像之后,这对我有帮助!
    • ContentID 不能包含“”字符。参数名称:System.Net.Mail.AttachmentBase.set_ContentId(String value) at ASP.research_aspx.ContentToAlternateView(String content) at ASP.research_aspx.SendMail(String subject, String body, String to) 处的值
    • 按照您的建议将 Content-ID 包装在 中肯定对我有用。它适用于 Thunderbird、Yahoo 和 Gmail 网络/电话应用程序。另请注意,Gmail 客户端可以选择“显示内嵌图像”,您需要单击/点击它。当您打开电子邮件时,您会看到该选项。
    • OP 也这样做了,不是尖括号。
    【解决方案4】:

    将其添加为 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" });
            }
    

    在我的班级MailService

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

    但我有另一个名为 Mail_Body 的方法,它返回一个 AlternateView 对象

    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 中的结果:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-08
      • 1970-01-01
      • 2013-10-10
      • 2011-01-11
      • 2018-09-24
      • 1970-01-01
      相关资源
      最近更新 更多