使用mailkit发送带有内嵌图片的邮件且图片不显示成附件
参考文章:mailkit---发送邮件
注意
在邮件客户端中是否显示内嵌图片为附件依据不同邮件有所不同,暂经测试outlook和qq不显示为附件,新浪邮箱会显示附件。
概述
要发送一封带有复杂格式的邮件,且正文内容中带有复杂的图片,以一封阿里云发送的邮件为例,其中还有5张图片。现在想要使用mailkit这个库来发送邮件,邮件模板中也含有图片,该如何发送呢。
知识点
mime-多用途互联网邮件扩展类型
一封含有复杂内容的邮件可以如下图表示,分为alternative、related、mixed三个部分,alternative部分包含纯文本和超文本内容,related包含alternative部分和内嵌资源,mixed部分包含related部分和附件。
文章中图片一般是作为图中的内嵌资源,所以不会出现在邮件的附件列表中。
实践
我们现在用这封阿里云的邮件作为模板,用mailkit发送这封邮件,且收到后的邮件效果相同。
准备工作
将邮件下载到本地,保存为html文件,并将邮件中用到的图片资源下载下来,将html文件和图片放在一个文件中一次作为一个模板。
代码实现
实现步骤主要问,组装正文部分包裹在alternative中,然后将alternative和内嵌资源包裹在related中,再将related用mixed包裹,将以上内容复制给邮件正文。
图片的链接进行格式处理,原:<img src="xxx/xxx/xx.jpg"/>,修改为<img src="cid:aaaaaaaa"/>。详见代码中射击contentid部分。
使用bodybuilder来构建邮件正文。具体见代码。
public bool sendemailtosingle(string toemail, string subject, string formatid) { try { var message = new mimemessage(); message.to.add(new mailboxaddress(toemail)); message.from.add(new mailboxaddress(emaildisplayname, emailusername)); message.subject = subject; // 获取邮件模板 string fullformatpath = path.combine(environment.currentdirectory, "content", formatid); string[] imgpaths = directory.getfiles(path.combine(fullformatpath, "resources")); string htmlformat = string.empty; var builder = new bodybuilder(); using (filestream fs = new filestream(path.combine(fullformatpath, "format.htm"), filemode.open)) { using (streamreader sr = new streamreader(fs, encoding.getencoding("gbk"))) { htmlformat = sr.readtoend(); } } // 将图片加入内嵌资源,并更换邮件中的图片的链接 foreach (string imgpath in imgpaths) { var image = builder.linkedresources.add(imgpath); image.contentid = mimeutils.generatemessageid(); htmlformat = htmlformat.replace(path.getfilename(imgpath), string.format("cid:{0}", image.contentid)); } builder.htmlbody = htmlformat; message.body = builder.tomessagebody(); //return message; using (smtpclient client = new smtpclient()) { client.servercertificatevalidationcallback = (s, c, h, e) => true; client.connect(emailserveraddress, emailserverport, false); client.authenticate(emailusername, emailpassword); client.send(message); client.disconnect(true); } return true; } catch (exception) { return false; } }
发送后收到的邮件
如对本文有疑问, 点击进行留言回复!!
使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)
C#实现获取本地内网(局域网)和外网(公网)IP地址的方法分析
网友评论