【问题标题】:How to send embedded images with sendgrid emails?如何使用 sendgrid 电子邮件发送嵌入的图像?
【发布时间】:2013-03-23 02:34:14
【问题描述】:

我开始使用 SendGrid 发送我的电子邮件,但我不知道如何嵌入图像。在不使用 SendGrid 的情况下,我使用以下代码发送带有嵌入图像的电子邮件:

var mail = new System.Net.Mail.MailMessage();
mail.Subject = "Warning";
mail.From = "from_user@test.com";
mail.To.Add("to_user@test.com");
mail.IsBodyHtml = true;
mail.Body = "<html><body><a href='http://www.mywebsite.com' title='My Website'><img src='cid:my_image' alt='My Image' border='0' /></a><br /><h1>My E-mail Title</h1>E-mail content.</body></html>";
var av = AlternateView.CreateAlternateViewFromString(mail.Body, null, "text/html");
av.LinkedResources.Add(new LinkedResource(@"C:\my_image.png", "image/png"){ContentId="my_image"});
mail.AlternateViews.Add(av);
var smtp = new SmtpClient("smtp.test.com");
smtp.Credentials = new NetworkCredential("user", "pass");
smtp.Send(mail);

--- 已编辑 ---

现在我正在使用以下代码发送我的电子邮件(使用 SendGrid 类)。

var message = SendGrid.GetInstance();
message.Subject = "Warning";
message.From = new MailAddress("from_user@test.com");
message.To = new MailAddress[] { new MailAddress("to_user@test.com") };
message.Html = "<html><body><a href='http://www.mywebsite.com' title='My Website'><img src='cid:my_image' alt='My Image' border='0' /></a><br /><h1>My E-mail Title</h1>E-mail content.</body></html>";
var transportSMTP = SMTP.GetInstance(new NetworkCredential("user", "pass"));
transportSMTP.Deliver(message);

我需要知道的是如何使用其内容 ID (CID) 在电子邮件中嵌入和链接我的图像。

【问题讨论】:

  • 您能告诉我们您现在使用的代码吗?
  • 为什么不能使用相同的代码?
  • 我已经添加了我现在使用的代码。要使用 sendgrid 发送电子邮件,我使用的是他们自己的类。这是一个下载链接:github.com/sendgrid/sendgrid-csharp。我可以使用默认的 .net 类通过 sendgrid 发送邮件吗?
  • 是的,您可以使用默认的 .net 类发送电子邮件。只需将其配置为指向smtp.sendgrid.net。您真正想要使用 SendGrid 库的唯一一次是,如果您广泛使用 X-SMTPAPI 标头,该库使该标头变得更容易
  • 我遇到了同样的问题。使用 SendGrid api 发送电子邮件,以便我可以嵌入独特的参数并且无法弄清楚如何嵌入图像。有没有人使用 C# 包装器让它工作:github.com/sendgrid/sendgrid-csharp

标签: .net email sendgrid


【解决方案1】:

对于任何寻找更简单的东西的人,您可以使用 Base64 对图像文件进行编码,然后将其作为字符串直接嵌入到电子邮件的 html 正文中,这对我有用,因为我只想在电子邮件中包含一个小徽标签名:

<img alt="My Image" src="data:image/jpeg;base64,/9j/4S/+RXhpZgAATU0AKgAAAAgACAESAAMAENkDZ5u8/61a+X...more encoding" />

【讨论】:

  • 请注意,(基于网络的)邮件客户端不太支持此功能!
【解决方案2】:

对于在通过 SendGrid 发送电子邮件中的嵌入图像并使用存储的模板时遇到困难的任何人,它的工作原理如下:

/* In my case the images reside in the SQL DB as BLOBs but for this example it does not matter.
All you need is an array of bytes with your image.
*/
var imageContent = File.ReadAllBytes("Images\\logo_eml.jpg");
using (MemoryStream s = new MemoryStream(imageContent))
{
    ContentType ctype = new ContentType("image/jpg");
    var attachment = new System.Net.Mail.Attachment(s, ctype);
    var linkedResource = new LinkedResource(s, ctype);
    attachment.Name = "cibc_ins_logo_eml.jpg";
    emailMsg.AddAttachment(attachment.ContentStream, attachment.Name);
    emailMsg.EmbedImage(attachment.Name, linkedResource.ContentId + ".jpg");

    values.Add("%embedLogo%", linkedResource.ContentId + ".jpg");
}

string templateJSON = "{\"to\": [\"%to%\"],\r \"sub\": {\":name\": [\"%name%\"],\":embedLogo\": [\"%embedLogo%\"]},\r \"category\": [\"Quotes\"],\r \"filters\": {\"templates\": {\"settings\": {\"enable\": 1,\"template_id\": \"%templateid%\"}}}}"
emailMsg.Headers.Add("x-smtpapi", SubstituteTemplate(templateJSON, values));

最后一行将替换这些值。就我而言,它只是进行正则表达式替换。此代码必须注意将您的特定 JSON 中的 %embedLogo% 替换为之前存储在 values 中的 linkedResource.ContentId+".jpg" 值,即 Dictionary&lt;string,string&gt;

这是您在存储的 HTML 模板中需要的内容:

<img width="227" height="86" src="cid::embedLogo">

CID 和两个冒号很关键。

然后,Gmail 将显示嵌入的图像,而不仅仅是附加的!

【讨论】:

    【解决方案3】:

    我也玩弄了一会儿。解决方案是先附加图像,然后在电子邮件中使用文件的直接名称嵌入。

    var myMessage = new SendGridMessage();
    myMessage.AddTo("to@email.com");
    myMessage.From = "from@email.com";
    myMessage.Subject ="Forgotten Password";
    string body = @"<div><img src='cid:email_reset' alt='Email Reset Header' border='0' /></div>" +
                  @"<p>Content...</p>";
    
    string att = Request.PhysicalApplicationPath + @"Content\files\images\email_reset.jpg";
    var attachment = new Attachment(att, new ContentType("image/jpeg"));
    var linkedResource = new LinkedResource(att, new ContentType("image/jpeg"));
    myMessage.AddAttachment(attachment.ContentStream, attachment.Name);
    myMessage.EmbedImage(attachment.Name, "email_reset");
    
    myMessage.Text = WebUtility.HtmlDecode(Regex.Replace(body, "<[^>]*(>|$)", string.Empty));
    myMessage.Html = body;
    
    // Authenticate and Send the email
    

    【讨论】:

    • 是否在任何地方使用了linkedResource?好像是多余的代码?
    【解决方案4】:

    我与一位 SendGrid 客户支持工程师交谈,他指导我到这里..

    https://github.com/sendgrid/sendgrid-csharp/blob/ca91fad22dfec2cd1219267fe979c1d9a33a522e/SendGrid/SendGridMail/SendGrid.cs#L211

    所以你的代码是……

    var message = SendGrid.GetInstance();
    message.Subject = "Warning";
    message.From = new MailAddress("from_user@test.com");
    message.To = new MailAddress[] { new MailAddress("to_user@test.com") };
    message.Html = "<html><body><a href='http://www.mywebsite.com' title='My Website'><img src='cid:my_image' alt='My Image' border='0' /></a><br /><h1>My E-mail Title</h1>E-mail content.</body></html>";
    
    // added    
    message.EmbedImage(@"C:\my_image.png","my_image");
    // added
    
    var transportSMTP = SMTP.GetInstance(new NetworkCredential("user", "pass"));
    transportSMTP.Deliver(message);
    

    我正在寻找一种方法来添加 MemoryStream 对象而不是文件名,看起来这似乎还不可用。

    【讨论】:

    • 其实是这样。从类似的问题中看一下这个分析器:stackoverflow.com/a/27362265/292230。您可以使用 MemoryStream 而不是文件名来实例化 LinkedResource。
    • 我正在使用MemoryStream 从数据库加载图像,但没有使用EmbedImage,并且附加的图像在 Outlook 中可以正常工作,但在 Gmail 中却不行。我尝试了各种EmbedImage() 呼叫无济于事 - Outlook 总是有效,Gmail 永远不会。我准备跳窗了。
    猜你喜欢
    • 1970-01-01
    • 2018-03-13
    • 1970-01-01
    • 2018-11-08
    • 1970-01-01
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 2012-04-07
    相关资源
    最近更新 更多