С# отправка писем со встроенными изображениями с использованием 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.