С# отправка писем со встроенными изображениями с использованием SmtpClient

SmtpClient() позволяет добавлять вложения в ваши письма, но что делать, если вы хотите сделать изображение, когда почта открывается, а не прикреплять его?

Как я помню, это можно сделать примерно с 4 строками кода, но я не помню, как и не могу найти его на сайте MSDN.

EDIT: я не использую веб-сайт или что-то еще, даже не IP-адрес. Изображение расположены на жестком диске. При отправке они должны быть частью почты. Итак, я думаю, я мог бы использовать тег... но я не уверен, потому что мой компьютер не транслируется.

Ответ 1

Одним из часто упоминаемых решений является добавление изображения в текст Attachment к почте, а затем ссылка на него в почтовом ящике HTML с помощью ссылки cid:.

Однако, если вы используете коллекцию LinkedResources, встроенные изображения будут по-прежнему отображаться просто отлично, но не будут отображаться в качестве дополнительных вложений для почты. Это то, что мы хотим сделать, так что я здесь:

using (var client = new SmtpClient())
{
    MailMessage newMail = new MailMessage();
    newMail.To.Add(new MailAddress("[email protected]"));
    newMail.Subject = "Test Subject";
    newMail.IsBodyHtml = true;

    var inlineLogo = new LinkedResource(Server.MapPath("~/Path/To/YourImage.png"));
    inlineLogo.ContentId = Guid.NewGuid().ToString();

    string body = string.Format(@"
            <p>Lorum Ipsum Blah Blah</p>
            <img src=""cid:{0}"" />
            <p>Lorum Ipsum Blah Blah</p>
        ", inlineLogo.ContentId);

    var view = AlternateView.CreateAlternateViewFromString(body, null, "text/html");
    view.LinkedResources.Add(inlineLogo);
    newMail.AlternateViews.Add(view);

    client.Send(newMail);
}

ПРИМЕЧАНИЕ.. Это решение добавляет AlternateView к вашему MailMessage типа text/html. Для полноты вы также должны добавить AlternateView типа text/plain, содержащий текстовую версию электронной почты для почтовых клиентов, отличных от HTML.

Ответ 2

HTML-адрес электронной почты и изображения являются вложениями, поэтому это всего лишь случай обращения к изображениям (-ами) их идентификаторами содержимого, т.е.

    Dim A As System.Net.Mail.Attachment = New System.Net.Mail.Attachment(txtImagePath.Text)
    Dim RGen As Random = New Random()
    A.ContentId = RGen.Next(100000, 9999999).ToString()
    EM.Body = "<img src='cid:" + A.ContentId +"'>" 

Здесь, по-видимому, есть исчерпывающие примеры: Отправить электронную почту с встроенными изображениями

Ответ 3

Когда вы говорите 4 строки кода, вы имеете в виду this?

System.Net.Mail.Attachment inline = new System.Net.Mail.Attachment(@"imagepath\filename.png");
inline.ContentDisposition.Inline = true;

Ответ 4

Как преобразовать изображения в строки Base64? AFAIK это может быть легко встроено в тело письма.

Посмотрите здесь.

Ответ 5

Решение уже опубликовано - это лучшее, что я нашел, я просто завершу его, например, если у вас несколько изображений.

        string startupPath = AppDomain.CurrentDomain.RelativeSearchPath;
        string path = Path.Combine(startupPath, "HtmlTemplates", "NotifyTemplate.html");
        string body = File.ReadAllText(path);

        //General tags replacement.
        body = body.Replace("[NOMBRE_COMPLETO]", request.ToName);
        body = body.Replace("[ASUNTO_MENSAJE]", request.Subject);

        //Image List Used to replace into the template.
        string[] imagesList = { "h1.gif", "left.gif", "right.gif", "tw.gif", "fb.gif" };

        //Here we create link resources one for each image. 
        //Also the MIME type is obtained from the image name and not hardcoded.
        List<LinkedResource> imgResourceList = new List<LinkedResource>();
        foreach (var img in imagesList)
        {
            string imagePath = Path.Combine(startupPath, "Images", img);
            var image = new LinkedResource(imagePath, "image/" + img.Split('.')[1]);
            image.ContentId = Guid.NewGuid().ToString();
            image.ContentType.Name = img;
            imgResourceList.Add(image);
            body = body.Replace("{" + Array.IndexOf(imagesList, img) + "}", image.ContentId);
        }

        //Altern view for managing images and html text is created.
        var view = AlternateView.CreateAlternateViewFromString(body, null, "text/html");
        //You need to add one by one each link resource to the created view
        foreach (var imgResorce in imgResourceList)
        {
            view.LinkedResources.Add(imgResorce);
        }

        ThreadPool.QueueUserWorkItem(o =>
        {
            using (SmtpClient smtpClient = new SmtpClient(servidor, Puerto))
            {
                smtpClient.EnableSsl = true;
                smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
                smtpClient.Timeout = 50000;
                smtpClient.UseDefaultCredentials = false;
                smtpClient.Credentials = new System.Net.NetworkCredential()
                {
                    UserName = UMail,
                    Password = password
                };
                using (MailMessage mailMessage = new MailMessage())
                {
                    mailMessage.IsBodyHtml = true;
                    mailMessage.From = new MailAddress(UMail);
                    mailMessage.To.Add(request.ToEmail);
                    mailMessage.Subject = "[NAPNYL] " + request.Subject;
                    mailMessage.AlternateViews.Add(view);
                    smtpClient.Send(mailMessage);
                }
            }
        });

Как вы видите, у вас есть массив имен изображений, важно, чтобы изображения находились в одной папке, потому что они указывали на одну и ту же папку вывода.

Наконец, письмо отправляется как асинхронное, поэтому пользователю не нужно ждать его отправки.

Ответ 6

Процесс создания изображения на клиенте при открытии почты - это клиентская функция. Пока клиент знает, как визуализировать изображение и не заблокировал какое-либо изображение, он сразу откроет его. Вам не нужно делать ничего особенного, отправляя электронное письмо, чтобы оно было открыто на клиенте, если вы правильно указали тип прикрепления изображения mime.