How to insert a resource image, as embedded image in email?

1 篇文章 0 订阅

最近项目需要,要在某种情况下,给用户发送邮件,以前的做法就是把邮件内容做成模板,在使用的时候,代码里面组装成HTML格式的邮件,只能是纯文本的。现在需要给邮件加背景图片以及一些图片,找寻了很多,发现很多人在做这些事情,其中有从网上看到的,也有我自己实现的,现在汇总如下:

.NET(C#):使用SmtpClient发送带有图片和附件的电子邮件

使用SmtpClient发送邮件的步骤就不讲了,在网上你可以找到太多的资料了,这里说一些需要注意的地方:如果邮件的内容是HTML,设置MailMessage.IsBodyHtml为True,这样邮件才能够被正确以HTML形式读取。在HTML中引用资源使用cid:xxx,xxx是附件的ContentId属性。同时也可以在MailMessage中的AlternateViews中加入AlternateView来指定电子邮件内容的不同格式。通过AlternativeView的LinkedResources来加入引用文件。引用也是通过LinkedResource的ContentId来设置的。事实上这个ContentId属性是来自AttachmentBase类型,而Attachment,AlternateView和LinkedResource类型都继承与这个类.

另外邮件的内容,主题,地址名称如果包含某些非ASCII字符的话应该指定一个编码,因为默认编码是ASCII。
最后某些SMTP服务器可能不支持SSL传输,因此SmtpClient的EnableSsl只能为false(否则会有异常抛出)。这种情况下,我们就需要使用下面列出的第二种方式,发送邮件。


第一种方式,使用Attachment:

                //图像附件
                var attach = new Attachment(@"D:\test.jpg", MediaTypeNames.Image.Jpeg);
                //设置ContentId
                attach.ContentId = "pic";
                //ZIP附件
                var attach2 = new Attachment(@"D:\test.zip", "application/x-zip-compressed");
 
                mail.Attachments.Add(attach);
                mail.Attachments.Add(attach2);
 
                //因为默认编码是ASCII
                mail.SubjectEncoding = Encoding.UTF8;
                //HTML内容
                mail.Body = "<img src=\"cid:pic\"/><p>设置图片。</p>";

第二种方式,使用LinkedResource,直接从绝对路径载入图片或者附件

来源于:Using LinkedResource Class for Sending HTML E-mail in .NET 2.0

To create an embedded image we will need to first create an HTML view of the email using AlternateView class. Within that alternate view we need to create a tag that points to the ContentId (cid) of the LinkedResource of the image view as shown below.
Listing 1 – Sample for HTML view
// to embed images, we need to use the prefix 'cid' in the img src value
string htmlBody = "<b>This is the embedded image file.</b><DIV> </DIV>";
htmlBody += "<img alt=\"\" hspace=0 src=\"cid:uniqueId\" align=baseline border=0 >";
htmlBody += "<DIV> </DIV><b>This is the end of Mail...</b>";
AlternateView htmlView = AlternateView.CreateAlternateViewFromString(htmlBody, 
    null, "text/html");

Then we need to create a LinkedResource object and add it to the AlternateView's LinkedResources Collection. Again, before adding this be sure to set the ContentId property of LinkedResource class as that unique value set in the HTML tag of AlternateView (i.e. cid). Here we need to set the TransferEncoding property of LinkedResource to Base64 which is the default for the image.

Listing 2 – Sample for Image resource
// create the image resource from image path using LinkedResource class..            
LinkedResource imageResource = new LinkedResource("c:\\attachment\\image1.jpg" , 
    "image/jpeg");
imageResource.ContentId = "uniqueId";
imageResource.TransferEncoding = TransferEncoding.Base64;
Here "uniqueId" is the common unique cid value. Let us add the above "imageResource" to "htmlView."
Listing 3 – Sample for adding Image in HTML part

// adding the imaged linked to htmlView...
htmlView.LinkedResources.Add(imageResource);
Then we have to add this htmlView (AlternateView object) to the MailMessage object.
Listing 4 – Setting the mail message
// add the view
mail.AlternateViews.Add(htmlView);

第三种方式,还是使用LinkedResource,不过是从stream中读出附件,然后添加进去,这个附件Build Action是Embedded Resource形式的:

                MemoryStream ms = null;

		strFile = "Modules.Resources.images.test.png";	
                using (Stream stream = asm.GetManifestResourceStream(strFile))
                {
                    byte[] bs = new byte[stream.Length];
                    stream.Read(bs, 0, (int)stream.Length);
			ms = new MemoryStream(bs);
                }
		LinkedResource lr = new LinkedResource(ms, "image/png");

其他和第二种方式类似,另外,背景图的添加类似于在代码里面加CSS style,
                //NO body += "</HEAD><BODY style=\"background: url(c:\\\\tt\\\\1.jpg) no-repeat fixed center;\">";
                //NO body += "</HEAD><BODY style=background-image:url(cid:backgroudpic);background-repeat:no-repeat;background-attachment:fixed;background-position:center;>";
                //NO body += "</HEAD><BODY style=\"background-image:url(cid:backgroudpic) background-repeat:no-repeat;\">";
                //NO body += "</HEAD><BODY style=\"background-image:url(cid:backgroudpic);background-repeat:no-repeat;\">";
                //NO body += "</HEAD><BODY style=background-image:url(cid:backgroudpic);background-repeat:no-repeat;>";
                //NO body += "</HEAD><BODY style=\"background-repeat:no-repeat;background-image:url(cid:backgroudpic);\">";
                //NO body += "</HEAD><BODY style=\"background: no-repeat fixed center url(cid:backgroudpic);\">";
                ///
                //OK body += "</HEAD><BODY style=background-image:url(cid:backgroudpic);><FONT face=Arial size=3>";
                //OK body += "</HEAD><BODY style=\"background-image:url(cid:backgroudpic);\"><FONT face=Arial size=3>";
                //OK body += "</HEAD><BODY style=\"background: url(cid:backgroudpic);\"><FONT face=Arial size=3>";
经测试,发现在C#代码中加入style,而且使用cid的形式,还不尽如人意,代码中NO的形式,是不能工作的形式,为什么不能加入no-repeat, fixed, center,原因还没找到。

使用CDO.Message发送带有图片和附件的电子邮件

尽管使用SmtpClient发送邮件很方便,不过某些SMTP服务器可能不支持SSL传输,因此SmtpClient的EnableSsl只能为false(否则会有异常抛出)。在这种情况下,就需要使用CDO.Message来发送邮件了。使用CDO发送邮件类似于这样的:
                CDO.Message msg = new CDO.Message();
                CDO.IConfiguration configuration = msg.Configuration;
                ADODB.Fields fields = configuration.Fields;

                ADODB.Field field = fields["http://schemas.microsoft.com/cdo/configuration/smtpserver"];
                field.Value = mailOptions.Server;				
		fields.Update();
                msg.Send();

其中fields可以参考: http://msdn.microsoft.com/en-us/library/exchange/ms872853(v=exchg.65).aspx
那么,如何添加类似于<img src=" cid:uniqueId ">呢?可以参看 CDO Support for MHTML
 If you want more control over constructing the MIME hierarchy itself, you can use the AddRelatedBodyPart method in conjunction with the IMessage.HTMLBody property. AddRelatedBodyPart automatically correlates the resource added as a body part to the message with the HTML that references it. This method creates the multipart/related hierarchy if required, and, depending upon your preference, associates the referenced resource in the HTML with the related body part using Content-Location or Content-ID headers.

重点是使用AddRelatedBodyPart 函数。

网上类似的资料很多,不过都是VB的,我还没找到C#中实现的。给出一个VB实现的,Embed an image in CDO e-mail

I had the need to generate nicely formatted e-mails from a website (IIS, ASP), which meant using images. Often times linked images are blocked from view by default in mail clients. Embedded images in HTML e-mail are more difficult to block within the client, but may be blocked at the SPAM/Filtering gateway level, especially if there are more than one embedded images, or if there is no other content except images. If you want more reliable delivery, use linked images. As a courtesy, it is common to provide a link at the top of the e-mail that says something like “If you can’t see the images in this e-mail, click here” which will load the same content from your web server in a browser. It can become tedious to manage, though. If you want better presentation, but risk less than 100% delivery, use embedded images.
Here’s a simple example of how to embed an image using CDO from ASP vbscript.bed an image in CDO e-mail
<%
Dim CDO, RBP
Set CDO = Server.CreateObject("CDO.Message")
CDO.MimeFormatted = True
CDO.To = "test@test.com"
CDO.From = """Test User"" test@test.com"
CDO.Subject = "E-mail with embedded image"
CDO.HTMLBody = "<html>Check this out: <img src=""cid:test.gif""></html>"
Set RBP = CDO.AddRelatedBodyPart(Server.MapPath("/images/test.gif"), "test.gif", 1)
RBP.Fields.Item("urn:schemas:mailheader:Content-ID") = "<test.gif>"
RBP.Fields.Update
CDO.Send
%>
这种我们如何用在C#中呢?
经本人实验,其实也蛮简单的。在<img  src="cid:uniqueId">中
                CDO.Message msg = new CDO.Message();
		msg.AddAttachment(@"c:\tt\1.jpg", null, null);
                msg.AddRelatedBodyPart(@"c:\tt\test.png", "uniqueId", CDO.CdoReferenceType.cdoRefTypeId, null, null);
这个是在设置完msg.HTMLBody之后,不过现在这种方式只能从绝对路径中获得文件,如何从stream中获得并发送之,一直没有找到方法?


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值