(C#) Изображение в почте не отображается в Outlook

Я хочу отправлять письма с изображениями в них. Написанный мной код работает нормально, но по какой-то неизвестной мне причине он не работает с клиентами Outlook. Я отправил тестовое письмо (слева: Thunderbird, справа: Outlook):

(C#) Изображение в почте не отображается в Outlook(C#) Изображение в почте не отображается в 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++;
    }
}

Итак, я пробовал разные решения, но ни одно из них не сработало. Мои шаги до сих пор:

  1. Я редактировал некоторые регистрационные ключи в HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\x.0\Outlook\Options\Mail или HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\x.0\Common

  2. Я оставил изображение как строку base64 в HTML

  3. Были добавлены некоторые свойства

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;

У меня ничего из этого не сработало, хотя казалось, что это помогло другим. Я что-то упустил?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
40
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы подтвердили, что это не блок изображений из настроек центра управления безопасностью.

Разблокировать загрузку изображений для одного сообщения: Щелкните информационную панель вверху сообщения. Щелкните Загрузить изображения.

Разблокировать загрузку изображений для всех сообщений: Outlook 2007 В меню «Инструменты» щелкните Центр управления безопасностью> Автоматическая загрузка. Снимите флажок «Не загружать изображения автоматически в сообщениях электронной почты HTML или в элементах RSS».

Outlook 2010 и более поздние версии: На вкладке «Файл» щелкните Параметры> Центр управления безопасностью. В Центре управления безопасностью Microsoft Outlook щелкните Параметры центра управления безопасностью. Снимите флажок «Не загружать изображения автоматически в сообщениях электронной почты HTML или в элементах RSS».

Разблокируйте загрузку изображений для всех сообщений с определенного адреса электронной почты или домена: В открытом сообщении, отправленном с определенного адреса электронной почты или домена, щелкните правой кнопкой мыши заблокированный элемент. Выполните одно из следующих действий:

  • Щелкните Добавить отправителя в список надежных отправителей.
  • Щелкните Добавить домен [@domain] в список надежных отправителей.

Образ действительно заблокирован центром доверия, но только его загрузка. После того, как я загрузил изображение вручную (или отключил блокировку изображений), я получаю пустое изображение, как показано в моем вопросе.

HimmDawg 30.03.2021 15:54

О, я понял. Вы бы выбрали обычное связывание изображений с сервера в Интернете?

sholistudios 30.03.2021 16:06

Изображения не могут быть сохранены на сервере перед отправкой по почте. Хотя я мог бы использовать абсолютные пути. Я не знаю, будет ли это иметь такой же эффект.

HimmDawg 30.03.2021 16:43
stackoverflow.com/questions/16242489/…
sholistudios 31.03.2021 03:05
Ответ принят как подходящий

Образы Base64 по умолчанию заблокированы в Outlook.

Вам необходимо прикрепить изображения к электронному письму и установить свойство PR_ATTACH_CONTENT_ID в электронном письме (имя DASL - «http://schemas.microsoft.com/mapi/proptag/0x3712001E»). См. Встраивать изображения в новые сообщения с помощью макроса для получения дополнительной информации.

Это недостающая информация, которая мне нужна. Спасибо :)

HimmDawg 31.03.2021 14:01

Другие вопросы по теме