Отправить HTML письмо со встроенным изображением и текст с тем же изображением, что и вложение в C#
Я хочу отправить электронное письмо с текстом и версией html. Для письма требуется изображение (оно не может быть размещено где-то еще), оно должно быть встроено, если клиент просматривает его в формате html, и прикреплено для просмотра в виде простого текста.
Возможно ли сделать так, чтобы это работало на всех общих клиентах?
Самое близкое, что я пришел, - это создание изображения в виде вложения (а не связанного ресурса), а затем ссылка на него в html с помощью cid:filename.jpg. Однако это не работает в Gmail (он не отображает изображение в HTML).
2 ответа
Этот фрагмент кода работает в Outlook 2010 и Gmail. Я проверяю текстовое электронное письмо, временно помещая текстовую часть последней в электронное письмо, что позволяет использовать ее в gmail.
Он также демонстрирует некоторые другие интересные вещи, такие как шаблоны электронной почты и подстановка тегов.
public void SendEmailWithPicture(string email, byte[] image)
{
string filename = "AttachmentName.jpg";
LinkedResource linkedResource = new LinkedResource(new MemoryStream(image), "image/jpg");
linkedResource.ContentId = filename;
linkedResource.ContentType.Name = filename;
this.Send(
EmailTemplates.sendpicture,
this.Subjects.SendPicture,
new List() { email },
this.ReplyTo,
tagValues: new Dictionary() { { "ImageAttachmentName", "cid:" + filename } },
htmlLinkedResources: new List() { linkedResource }
);
}
private void Send(EmailTemplates template, string subject, List to, string replyTo,
Dictionary tagValues = null, List attachments = null, List htmlLinkedResources = null)
{
try
{
MailMessage mailMessage = new MailMessage();
// Set up the email header.
to.ForEach(t => mailMessage.To.Add(new MailAddress(t)));
mailMessage.ReplyToList.Add(new MailAddress(replyTo));
mailMessage.Subject = subject;
string fullTemplatePath = Path.Combine(this.TemplatePath, EMAIL_TEMPLATE_PATH);
// Load the email bodies
var htmlBody = File.ReadAllText(Path.Combine(fullTemplatePath, Path.ChangeExtension(template.ToString(), "html")));
var textBody = File.ReadAllText(Path.Combine(fullTemplatePath, Path.ChangeExtension(template.ToString(), "txt")));
// Replace the tags in the emails
if (tagValues != null)
{
foreach (var entry in tagValues)
{
string tag = "{{" + entry.Key + "}}";
htmlBody = htmlBody.Replace(tag, entry.Value);
textBody = textBody.Replace(tag, entry.Value);
}
}
// Create plain text alternative view
string baseTxtTemplate = File.ReadAllText(Path.Combine(fullTemplatePath, TXT_BASE_TEMPLATE));
textBody = baseTxtTemplate.Replace(TAG_CONTENT, textBody);
AlternateView textView = AlternateView.CreateAlternateViewFromString(textBody, new System.Net.Mime.ContentType("text/plain"));
// Create html alternative view
string baseHtmlTemplate = File.ReadAllText(Path.Combine(fullTemplatePath, HTML_BASE_TEMPLATE));
htmlBody = baseHtmlTemplate.Replace(TAG_CONTENT, htmlBody);
AlternateView htmlView = AlternateView.CreateAlternateViewFromString(htmlBody, new System.Net.Mime.ContentType("text/html"));
// Add any html linked resources
if (htmlLinkedResources != null)
{
htmlLinkedResources.ForEach(lr => htmlView.LinkedResources.Add(lr));
htmlLinkedResources.ForEach(lr => textView.LinkedResources.Add(lr));
}
// Add the two views (gmail will always display plain text version if its added last)
mailMessage.AlternateViews.Add(textView);
mailMessage.AlternateViews.Add(htmlView);
// Add any attachments
if (attachments != null)
{
attachments.ForEach(a => mailMessage.Attachments.Add(a));
}
// Send the email.
SmtpClient smtp = new SmtpClient();
smtp.Send(mailMessage);
}
catch (Exception ex)
{
throw new Exception(String.Format("Error sending email (to:{0}, replyto:{1})", String.Join(",", to), replyTo), ex);
}
}
Вид простого текста, это именно то. Это обычный текст, без видимых изображений. Вы можете прикрепить изображение, но вы не можете заставить его просмотреть его.
Взгляните на необработанные сообщения электронной почты, например, о том, как показывать встроенные вложения. В качестве примера приведем код, который сделал кто-то другой: http://blog.devexperience.net/en/12/Send_an_Email_in_CSharp_with_Inline_attachments.aspx
- Видимо, приведенная выше ссылка больше не действительна - быстрый Google предоставил следующий пример для встраивания изображения
string htmlBody = "<html><body><h1>Picture</h1><br><img src=\"cid:Pic1\"></body></html>";
AlternateView avHtml = AlternateView.CreateAlternateViewFromString
(htmlBody, null, MediaTypeNames.Text.Html);
// Create a LinkedResource object for each embedded image
LinkedResource pic1 = new LinkedResource("pic.jpg", MediaTypeNames.Image.Jpeg);
pic1.ContentId = "Pic1";
avHtml.LinkedResources.Add(pic1);
// Add the alternate views instead of using MailMessage.Body
MailMessage m = new MailMessage();
m.AlternateViews.Add(avHtml);
// Address and send the message
m.From = new MailAddress("email1@host.com", "From guy");
m.To.Add(new MailAddress("email2@host.com", "To guy"));
m.Subject = "A picture using alternate views";
SmtpClient client = new SmtpClient("mysmtphost.com");
client.Send(m);