如何用MailKit修复C#无法提取HTML div中邮件图片的问题?
解决MailKit无法保存HTML邮件div中内嵌图片的问题
你的代码仅遍历了邮件的顶层BodyParts,但HTML邮件里的内嵌图片(比如div中的<img>标签引用的资源)通常嵌套在MultipartRelated这类复合MIME部件中,不会出现在顶层部件列表里,因此会被遗漏。要解决这个问题,需要递归遍历邮件中的所有MIME部件,包括嵌套在复合部件里的子部件。
修复后的代码
首先添加一个递归遍历所有MIME部件的辅助方法,然后在原方法中调用它:
// 递归遍历所有MIME部件,提取图片 private void TraverseMimeParts(MimeEntity entity, List<EMailMessageAttachment> attachments, ref int counter, string subject) { if (entity is MimePart part) { // 筛选有ContentId的图片部件(内嵌图片通常会设置ContentId供HTML引用) if (!string.IsNullOrEmpty(part.ContentId) && part.ContentObject != null && part.ContentType.MediaType.Equals("image", StringComparison.OrdinalIgnoreCase)) { byte[] byteCode; using (var mem = new MemoryStream()) { part.ContentObject.DecodeTo(mem); byteCode = mem.ToArray(); } attachments.Add(new EMailMessageAttachment { FileName = $"{subject}_{counter}.jpg", Content = byteCode }); counter++; } } else if (entity is Multipart multipart) { // 递归处理复合部件下的所有子部件 foreach (var subEntity in multipart) { TraverseMimeParts(subEntity, attachments, ref counter, subject); } } } // 主方法调用递归遍历 private void AttachPicturesFromMessage(MimeMessage message, List<EMailMessageAttachment> attachments) { var counter = 1; TraverseMimeParts(message.Body, attachments, ref counter, message.Subject); }
关键说明
- 递归遍历:邮件的MIME结构是树形的,复合部件(如
MultipartAlternative、MultipartRelated)会包含子部件,递归遍历能覆盖所有层级的图片。 - ContentId判断:HTML中的内嵌图片通常通过
cid:协议引用,对应的图片部件会设置ContentId,这个判断能准确筛选出这类内嵌资源。 - 大小写不敏感匹配:
MediaType的匹配使用StringComparison.OrdinalIgnoreCase,避免因Image和image的大小写差异漏判。
注意:如果div中的图片是远程URL(而非内嵌到邮件的cid资源),此方法无法保存这类图片,因为它们不属于邮件的附件/内嵌部件,需要额外的网络请求下载。
内容的提问来源于stack exchange,提问作者Alldman
相关产品推荐
相关产品推荐

