Я хочу отправлять письма с изображениями в них. Написанный мной код работает нормально, но по какой-то неизвестной мне причине он не работает с клиентами Outlook. Я отправил тестовое письмо (слева: Thunderbird, справа: Outlook):
Что должен делать мой код: он берет RTF из RichTextBox
и преобразует его в HTML. Это оставляет изображения встроенными в HTML в виде строк base64. Я извлекаю все изображения в кодировке base64 одно за другим и помещаю их в MemoryStream
, который принимает LinkedResource
. Поскольку почтовые клиенты обычно не принимают встроенные изображения, я заменяю встроенное изображение в HTML на идентификатор содержимого. Затем я устанавливаю некоторые свойства LinkedResource
и добавляю их в AlternateView
. Этот альтернативный вид затем добавляется в System.Net.Mail.MailMessage
, и письмо отправляется.
Соответствующий код:
MemoryStream mem = null;
private readonly Regex embeddedImageRegex = new Regex("src=\"data:image/.*?\"");
public MyHTMLMailMessage()
: base()
{
this.SubjectEncoding = Encoding.UTF8;
this.BodyEncoding = Encoding.UTF8;
this.IsBodyHtml = true;
}
public bool Send()
{
// create HTML View with images
AlternateView htmlView = AlternateView.CreateAlternateViewFromString(HTML, System.Text.Encoding.UTF8, MediaTypeNames.Text.Html);
ReplaceEmbeddedImagesWithCID(htmlView);
this.AlternateViews.Add(htmlView);
this.Body = HTML;
SmtpClient client = new SmtpClient(server, port);
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = String.IsNullOrEmpty(username);
try
{
client.Send(this);
return true;
}
catch (SmtpException e)
{
return false;
}
finally
{
mem?.Close();
}
}
private void ReplaceEmbeddedImagesWithCID(AlternateView altView)
{
string extension;
int imageIndex = 0;
string contentID = $"image{imageIndex}";
// go through every base64 string, create a content id and LinkedResource for it
while (embeddedImageRegex.IsMatch(HTML))
{
extension = new Regex("image/.*?;").Match(HTML).Value
.Replace("image/", "")
.Replace(";", "");
string base64img = embeddedImageRegex.Match(HTML).Value
.Replace("src=\"", "")
.Replace("\"", "")
.Split(',')[1];
HTML = embeddedImageRegex.Replace(HTML, $"src=\"cid:image{imageIndex}\"", 1);
byte[] byBitmap = Convert.FromBase64String(base64img);
mem = new MemoryStream(byBitmap);
mem.Position = 0;
LinkedResource linkedImage = new LinkedResource(mem, $"image/{extension}");
linkedImage.ContentId = contentID;
altView.LinkedResources.Add(linkedImage);
altView = AlternateView.CreateAlternateViewFromString(HTML, null, MediaTypeNames.Text.Html);
imageIndex++;
}
}
Итак, я пробовал разные решения, но ни одно из них не сработало. Мои шаги до сих пор:
Я редактировал некоторые регистрационные ключи в
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\x.0\Outlook\Options\Mail
илиHKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\x.0\Common
Я оставил изображение как строку base64 в HTML
Были добавлены некоторые свойства
linkedImage.TransferEncoding = TransferEncoding.Base64;
linkedImage.ContentType.Name = contentID;
linkedImage.ContentLink = new Uri($"cid:{contentID}");
this.Headers.Add("Content-ID", $"<image{imageIndex}>");
this.Headers.Add("X-Attachment-Id", $"image{imageIndex}");
altView.TransferEncoding = TransferEncoding.QuotedPrintable;
У меня ничего из этого не сработало, хотя казалось, что это помогло другим. Я что-то упустил?
2 ответа
Образы Base64 по умолчанию заблокированы в Outlook.
Вам необходимо прикрепить изображения к электронному письму и установить свойство PR_ATTACH_CONTENT_ID
в электронном письме (имя DASL - "http://schemas.microsoft.com/mapi/proptag/0x3712001E"). См. Встраивание изображений в новые сообщения с помощью макроса за дополнительной информацией.
Подтвердили ли вы, что это не блок изображений из настроек центра управления безопасностью.
Разблокировать загрузку изображений для одного сообщения: Щелкните информационную панель вверху сообщения. Щелкните Загрузить изображения.
Разблокировать загрузку изображений для всех сообщений: Outlook 2007 В меню «Инструменты» щелкните Центр управления безопасностью> Автоматическая загрузка. Снимите флажок «Не загружать изображения автоматически в сообщениях электронной почты HTML или в элементах RSS».
Outlook 2010 и более поздние версии: На вкладке «Файл» щелкните Параметры> Центр управления безопасностью. В Центре управления безопасностью Microsoft Outlook щелкните Параметры центра управления безопасностью. Снимите флажок «Не загружать изображения автоматически в сообщениях электронной почты HTML или в элементах RSS».
Разблокируйте загрузку изображений для всех сообщений с определенного адреса электронной почты или домена: В открытом сообщении, отправленном с определенного адреса электронной почты или домена, щелкните правой кнопкой мыши заблокированный элемент. Выполните одно из следующих:
- Щелкните Добавить отправителя в список надежных отправителей.
- Щелкните Добавить домен [@domain] в список надежных отправителей.
Похожие вопросы
Связанные вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.