如何解决C# MailMessage嵌入带链接多图仅显示最后一张的问题
C# MailMessage 多嵌入图片仅显示最后一张的修复
根因定位
原代码在循环内重复创建AlternateView实例,导致前序图片资源全部丢失:
- 每轮遍历图片时,都会通过
AlternateView.CreateAlternateViewFromString生成全新的View对象,上一轮生成的View实例直接被临时变量覆盖,持有的图片资源随之丢失 - 每轮仅将当前图片对应的
LinkedResource挂载到本轮临时生成的View上,最终返回的View实例虽然包含了完整的5个图片标签的HTML代码,但仅关联了最后1张图片的嵌入资源 - 邮件客户端解析HTML时,会根据
img标签里的CID值匹配对应的嵌入资源,前4张图的CID没有对应附加资源,自然无法加载,只有最后一张图有对应资源,因此仅显示最后一张图。
修复后代码
调整逻辑顺序:先完成所有HTML内容拼接、所有嵌入资源初始化,仅创建一次AlternateView实例,最后统一挂载全部嵌入资源:
private AlternateView GetEmbeddedImage(List<string> images) { string body = string.Empty; const string linkTemplate = "<a href='http://localhost:55148/Support/Management/Index'>"; List<LinkedResource> allImageResources = new List<LinkedResource>(); for (int i = 0; i < images.Count; i++) { string filePath = images[i]; LinkedResource imageRes = new LinkedResource(filePath, MediaTypeNames.Image.Jpeg); // 生成唯一ContentId,和img标签的cid值一一对应 imageRes.ContentId = Guid.NewGuid().ToString(); // 累积拼接完整的带超链接的图片HTML片段 body += linkTemplate + $"<img src='cid:{imageRes.ContentId}' />" + "</a>"; allImageResources.Add(imageRes); } // 仅创建一次HTML格式的AlternateView AlternateView alternateView = AlternateView.CreateAlternateViewFromString( body, null, MediaTypeNames.Text.Html); // 统一挂载所有嵌入图片资源 foreach (var res in allImageResources) { alternateView.LinkedResources.Add(res); } return alternateView; }
踩坑提示
- 嵌入图片的
ContentId值必须和HTML中img标签src属性里cid:后的字符串完全匹配,区分大小写 - 同一HTML格式的邮件正文只需要对应1个
AlternateView实例,所有嵌入资源统一挂载到该实例下即可,不需要为每张图单独创建View - 所有
LinkedResource对象在添加到View前,要确保文件路径有效,没有被提前释放
内容的提问来源于stack exchange,提问作者Rani Radcliff
相关产品推荐
相关产品推荐

