C# 使用 SmtpClient 发送带有内联图像的邮件

发布于 2024-07-30 18:10:08 字数 225 浏览 8 评论 0原文

SmtpClient() 允许您向邮件添加附件,但是如果您想在邮件打开时显示图像而不是附加附件,该怎么办?

我记得,大约需要 4 行代码就可以完成,但我不记得如何完成,并且在 MSDN 网站上找不到它。

编辑:我没有使用网站或任何东西,甚至没有IP地址。 图像位于硬盘上。 发送时,它们应该是邮件的一部分。 所以,我想我可能想使用标签......但我不太确定,因为我的计算机没有广播。

SmtpClient() allows you to add attachments to your mails, but what if you wanna make an image appear when the mail opens, instead of attaching it?

As I remember, it can be done with about 4 lines of code, but I don't remember how and I can't find it on the MSDN site.

EDIT: I'm not using a website or anything, not even an IP address. The image(s) are located on a harddrive. When sent, they should be part of the mail. So, I guess I might wanna use an tag... but I'm not too sure, since my computer isn't broadcasting.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

伤痕我心 2024-08-06 18:10:08

经常提到的一种解决方案是将图像作为附件 添加到邮件中,然后使用cid: 引用在 HTML 邮件正文中引用它。

但是,如果您改用 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"), "image/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。 为了完整起见,您还应该添加 text/plain 类型的 AlternateView,其中包含用于非 HTML 邮件客户端的电子邮件的纯文本版本。

One solution that is often mentioned is to add the image as an Attachment to the mail, and then reference it in the HTML mailbody using a cid: reference.

However if you use the LinkedResources collection instead, the inline images will still appear just fine, but don't show as additional attachments to the mail. That's what we want to happen, so that's what I do here:

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"), "image/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);
}

NOTE: This solution adds an AlternateView to your MailMessage of type text/html. For completeness, you should also add an AlternateView of type text/plain, containing a plain text version of the email for non-HTML mail clients.

2024-08-06 18:10:08

HTML 电子邮件和图像是附件,因此这只是通过内容 ID 引用图像的情况,即

    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 +"'>" 

这里似乎有全面的示例: 发送带有内嵌图像的电子邮件

The HTML Email and the images are attachments so it's just a case of referring to the image(s) by their content ids, i.e.

    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 +"'>" 

There seems to be comprehensive examples here: Send Email with inline images

原谅过去的我 2024-08-06 18:10:08

当你说4行代码时,你指的是这个吗?

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

When you say 4 lines of code, are you referring to this?

System.Net.Mail.Attachment inline = new System.Net.Mail.Attachment(@"imagepath\filename.png");
inline.ContentDisposition.Inline = true;
人间☆小暴躁 2024-08-06 18:10:08

将图像转换为 Base64 字符串怎么样? 据我所知,这可以很容易地嵌入邮件正文中。

请查看此处

What about converting images in Base64 strings? AFAIK this can be easily embedded within mail body.

Take a look here.

夏の忆 2024-08-06 18:10:08

已经发布的解决方案是我发现的最好的解决方案,例如,如果您有多个图像,我将完成它。

        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);
                }
            }
        });

正如您所看到的,您有一个图像名称数组,图像位于同一文件夹中非常重要,因为它指向同一输出文件夹。

最后,电子邮件以异步方式发送,因此用户不必等待电子邮件发送。

The solution already posted is the best I have found, I'm just going to complete it with for example if you have multiple images.

        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);
                }
            }
        });

As you can see you have an array of image names, it is important that the images are in the same folder because it is pointing to the same output folder.

Finally the email is sent as async so the user doesn't have to wait for it to be sent.

逆蝶 2024-08-06 18:10:08

当打开邮件时使图像出现在客户端上的过程是客户端功能。 只要客户知道如何渲染图像& 没有阻止任何图像内容,它会立即打开它。 只要您正确指定了图像 MIME 附件类型,您在发送电子邮件时无需执行任何特殊操作即可在客户端上打开该电子邮件。

The process of making an image appear on the client when the mail is opened is a client function. As long as the client knows how to render the image & has not blocked any image content it will open it right away. You do not have to do anything special while sending the email to make it open on the client as long as you have correctly specified the image mime attachment type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文