如何在电子邮件中嵌入图片且不被列为附件,优化显示效果
到目前为止,我已经成功在使用RazorEngine渲染的邮件模板中嵌入了图片,但我对当前的显示效果并不满意。
可以看到,这些图片会被显示为附件,效果十分不美观。请问有哪些方案可以优化最终的输出效果?
相关实现代码
private async Task<MailMessage> PrepareEmailData(AppUser user) { var (body, models) = await PrepareHtmlContentWithModels(user); var emailMessage = new MailMessage { From = new MailAddress("someemail@gmail.com", "Bla-bla-bla"), Subject = "Weekly summary", IsBodyHtml = true, Body = body, Priority = MailPriority.Normal, }; emailMessage.To.Add(new MailAddress(user.Email)); var alternateView = AlternateView.CreateAlternateViewFromString(body, null, "text/html"); var imageLinks = new List<LinkedResource>(); models.BoardThreadWithRepliesModels.ForEach(e => imageLinks.Add(new LinkedResource(e.ThreadMainPicturePath, "image/png") { ContentId = e.ThreadMainPictureContentId, TransferEncoding = TransferEncoding.Base64 })); models.BoardThreadWithRepliesModels .ForEach(e => e.Replies .Where(r => !string.IsNullOrWhiteSpace(r.PicRelatedPath)) .ToList() .ForEach(r => { imageLinks.Add(new LinkedResource(r.PicRelatedPath, "image/png") { ContentId = r.PicRelatedContentId, TransferEncoding = TransferEncoding.Base64 }); })); imageLinks.ForEach(e => alternateView.LinkedResources.Add(e)); emailMessage.AlternateViews.Add(alternateView); return emailMessage; }
图片被识别为附件的问题,是因为内嵌资源的配置和邮件结构存在可优化的空间,以下是4种可行的优化方案:
方案1:修正内嵌资源的配置(优先级最高,改造成本最低)
你的代码中没有为LinkedResource指定内容处置类型,部分邮件客户端会默认将未标记为内联的资源识别为附件,只需要新增一行配置即可解决:
在创建LinkedResource时增加DispositionType = DispositionTypeNames.Inline,示例如下:
imageLinks.Add(new LinkedResource(e.ThreadMainPicturePath, "image/png") { ContentId = e.ThreadMainPictureContentId, TransferEncoding = TransferEncoding.Base64, // 新增这行,标记资源为内联显示,不是附件 DispositionType = System.Net.Mime.DispositionTypeNames.Inline });
同时建议删除MailMessage初始化时直接给Body赋值的逻辑,避免和AlternateView的内容冲突导致客户端解析异常:
var emailMessage = new MailMessage { From = new MailAddress("someemail@gmail.com", "Bla-bla-bla"), Subject = "Weekly summary", IsBodyHtml = true, // 删掉Body = body这行,由AlternateView提供内容 Priority = MailPriority.Normal, };
方案2:Base64直接内嵌到HTML
不需要使用LinkedResource,直接把图片转成Base64字符串写入HTML的img标签src属性中,格式为data:image/png;base64,{你的Base64字符串}。
该方案的优点是完全不会产生附件,缺点是单张图片过大会显著增加邮件体积,部分老旧邮件客户端不支持该格式。
方案3:使用外链图片
将图片上传到可公共访问的存储服务,邮件模板中直接填写图片的完整HTTP地址作为img的src属性。
该方案的优点是邮件体积最小,不会出现附件,缺点是部分邮件客户端默认会屏蔽外链图片,需要用户手动触发加载。
方案4:优化邮件资源的关联逻辑
如果邮件内图片数量较多,可以对相同的图片进行去重,避免重复添加LinkedResource,降低邮件体积的同时也能减少客户端解析异常的概率。
内容的提问来源于stack exchange,提问作者tokechu

