2011-08-13 114 views
11

我正在编写一个程序,将电子邮件发送给嵌入电子邮件正文(HTML)中的多个图像(图表)的用户。如何使用.NET在电子邮件正文中嵌入多个图像

当我尝试位于这里的示例..当我只需要嵌入一个图像 http://www.systemnetmail.com/faq/4.4.aspx

但是,当我试图嵌入多个图像使用下面的代码,没有任何图像被嵌入,而是他们作为附件发送。

public MailMessage MailMessage(Metric metric, DateTime date) 
{ 
    MailMessage msg = new MailMessage(); 
    msg.From = new MailAddress("[email protected]", "User1"); 
    msg.To.Add(new MailAddress("[email protected]")); 
    msg.Subject = "Trend for metric: " + metric.Name; 
    msg.IsBodyHtml = true; 

    // Generate the charts for the given metric 
    var charts = this.GenerateCharts(metric, date); 
    int i = 0; 
    string htmlBody = "<html><body>"; 
    List<LinkedResource> resources = new List<LinkedResource>(); 
    foreach (var chart in charts) 
    { 
     string imageTag = string.Format("<img src=cid:chart{0} /><br>", i); 
     htmlBody += imageTag; 
     LinkedResource graph = new LinkedResource(chart.Value, "image/jpeg"); 
     graph.ContentId = "chart" + i; 
     resources.Add(graph); 
     i++; 
    } 

    htmlBody += "</body></html>"; 

    // Alternate view for embedded images 
    AlternateView avText = AlternateView.CreateAlternateViewFromString(metric.Name, null, MediaTypeNames.Text.Html); 
    AlternateView avImages = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html); 

    // Add all the images as linked resources 
    resources.ForEach(x => avImages.LinkedResources.Add(x)); 

    // Add the views for image 
    msg.AlternateViews.Add(avText); 
    msg.AlternateViews.Add(avImages); 


    return msg; 
} 

作为我失踪的任何线索? 我检查它也被作为与电子邮件附件中的.htm文件,HTML源代码如下所示:

<html>><body><img src=cid:chart0 /><br><img src=cid:chart1 /><br><img src=cid:chart2/><br><img src=cid:chart3 /><br><img src=cid:chart4 /><br></body></html> 

所以Q是如何在HTML正文发送多张图片,而不是作为附件。

+1

可能的重复[发送电子邮件与图像嵌入在身体从C#](http://stackoverflow.com/questions/1921275/sending-an-email-with-an-image-embedded-in-the- body-from-c) –

回答

6

所以,我觉得想通了实际的问题是什么 其在这一行

// Alternate view for embedded images 
    AlternateView avText = AlternateView.CreateAlternateViewFromString(metric.Name, null, MediaTypeNames.Text.Html); 
    AlternateView avImages = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html); 

正如你所看到的,我的意见被指定为Text.Html,所以第一个1是压倒一切的下一个,所以我只能看到文字和图片作为附件发送

我做了如下的变化和它的工作如预期

AlternateView avText = AlternateView.CreateAlternateViewFromString(metric.Name, null, **MediaTypeNames.Text.Plain**); 
AlternateView avImages = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html); 
+0

我有确切的问题。这正是我期待的!但是,如果我最终使用了超过2张图片,我不完全确定如何创建每个AlternateView。我假设我能够使所有这些,但最后作为Text.Plain – roshambo

5

第一个,你可以尝试使用绝对URI来嵌入图像。下面是例如,从RFC-2557

From: [email protected] 
    To: [email protected] 
    Subject: A simple example 
    Mime-Version: 1.0 
    Content-Type: multipart/related; boundary="boundary-example"; 
      type="text/html"; start="<[email protected]@bar.net>" 

    --boundary-example 
    Content-Type: text/html;charset="US-ASCII" 
    Content-ID: <[email protected]@bar.net> 

    ... text of the HTML document, which might contain a URI 
    referencing a resource in another body part, for example 
    through a statement such as: 
    <IMG SRC="http://www.ietf.cnri.reston.va.us/images/ietflogo.gif" ALT="IETF logo"> 

    --boundary-example 
    Content-Location: 
    http://www.ietf.cnri.reston.va.us/images/ietflogo.gif 
    Content-Type: IMAGE/GIF 
    Content-Transfer-Encoding: BASE64 

    R0lGODlhGAGgAPEAAP/////ZRaCgoAAAACH+PUNvcHlyaWdodCAoQykgMTk5 
    NSBJRVRGLiBVbmF1dGhvcml6ZWQgZHVwbGljYXRpb24gcHJvaGliaXRlZC4A 
    etc... 

    --boundary-example-- 

你只需要分配LinkedResource.ContentLink property而不是内容识别。

第二,你可以直接将图像嵌入到您的HTML the "data" URL scheme

<IMG 
    SRC="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw 
    AAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFz 
    ByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSp 
    a/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJl 
    ZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uis 
    F81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PH 
    hhx4dbgYKAAA7" 
    ALT="Larry"> 

顺便说一句,你的html标记格式不正确。 您还可能有兴趣在“foreach” vs “ForEach”

+0

它是如何(html)结构不正常?你可以解释吗? – user330612

+0

我找到了解决方案,我的pblm,如下所述 – user330612

+0

绝对URI嵌入图像解决了我的问题谢谢你... –

1

如果你有在线图像,这意味着从一个托管网站发送,我建议你只是通过将他们的URL在src中引用这些图像。

<!-- using artplastika examples --> 
<IMG SRC="http://www.ietf.cnri.reston.va.us/images/ietflogo.gif" ALT="IETF logo" /> 

大部分通讯使用这种方法,我相信它更轻,可以比嵌入本身消耗更少的资源。

希望在使用System.Net.Mail

连接图像从本地驱动器,电子邮件和分配contentID它和后来的图像中使用此contentID这有助于

19

的另一种方式嵌入在电子邮件中的图像URL。

这可以这样做:

var contentID = "Image"; 
var inlineLogo = new Attachment(@"C:\Desktop\Image.jpg"); 
inlineLogo.ContentId = contentID; 
inlineLogo.ContentDisposition.Inline = true; 
inlineLogo.ContentDisposition.DispositionType = DispositionTypeNames.Inline; 

msg.IsBodyHtml = true; 
msg.Attachments.Add(inlineLogo); 
msg.Body = "<htm><body> <img src=\"cid:" + contentID + "\"> </body></html>"; 
+0

请不要发布完全相同的答案多个问题:它可能不适合所有或问题是重复的应该被标记/关闭。 – kleopatra

+0

你的方法为我工作。我尝试链接资源,但它没有奏效。几乎在我看来,每个人似乎都使用链接资源在电子邮件客户端中显示图像。奇怪的! –

+0

完美地工作。我不太了解需要使用链接的资源。我的口味更干净更优雅。 –

2

我alternatie:

首先,有一点延伸:

public static class RegexExtensions 
{ 
    public static string GetPattern(this IEnumerable<string> valuesToSearch) 
    { 
     return string.Format("({0})", string.Join("|", valuesToSearch)); 
    } 
} 

然后从文件夹获取图像名称:

private string[] GetFullNamesOfImages() 
    { 
     string images = Path.Combine(_directoryName, "Images"); 
     if (!Directory.Exists(images)) 
      return new string[0]; 
     return Directory.GetFiles(images); 
    } 

然后更换我通过CID法师的名字:

private string InsertImages(string body) 
    { 
     var images = GetFullNamesOfImages().Select(Path.GetFileName).ToArray(); 
     return Regex.Replace(body, "(Images/)?" + images.GetPattern(), "cid:$2", RegexOptions.IgnoreCase | RegexOptions.Compiled); 
    } 

其中体 - 是HTML的身体,例如,<img src="Images/logo_shadow.png" alt="" style="width: 100%;" />将由<img src="cid:logo_shadow.png" alt="" style="width: 100%;" />

那么最后一个动作所取代:添加图像itselfs至邮箱:

private MailMessage CreateMail(SmtpClient smtp, string toAddress, string body) 
    { 
     var images = GetFullNamesOfImages(); 

     string decodedBody = WebUtility.HtmlDecode(body); 
     var text = AlternateView.CreateAlternateViewFromString(decodedBody, null, MediaTypeNames.Text.Plain); 
     var html = AlternateView.CreateAlternateViewFromString(body, null, MediaTypeNames.Text.Html); 
     foreach (var image in images) 
     { 
      html.LinkedResources.Add(new LinkedResource(image, new ContentType("image/png")) 
            { 
             ContentId = Path.GetFileName(image) 
            }); 
     } 


     var credentials = (NetworkCredential) smtp.Credentials; 

     var message = new MailMessage(new MailAddress(credentials.UserName), new MailAddress(toAddress)) 
         { 
          Subject = "Some subj", 
          Body = decodedBody 
         }; 
     message.AlternateViews.Add(text); 
     message.AlternateViews.Add(html); 
     return message; 
    } 
1
 AlternateView avHtml = AlternateView.CreateAlternateViewFromString(body, null, MediaTypeNames.Text.Html); 
     LinkedResource inline = new LinkedResource(System.Web.HttpContext.Current.Server.MapPath("~/Images/e1.jpg"), MediaTypeNames.Image.Jpeg); 
     inline.ContentId = "1"; 
     inline.TransferEncoding = System.Net.Mime.TransferEncoding.Base64; 
     avHtml.LinkedResources.Add(inline); 

     LinkedResource inline1 = new LinkedResource(System.Web.HttpContext.Current.Server.MapPath("~/CImages/2.jpg"), MediaTypeNames.Image.Jpeg); 
     inline1.ContentId = "2"; 
     inline1.TransferEncoding = System.Net.Mime.TransferEncoding.Base64; 
     avHtml.LinkedResources.Add(inline1); 

     LinkedResource inline2 = new LinkedResource(System.Web.HttpContext.Current.Server.MapPath("~/Images/3.jpg"), MediaTypeNames.Image.Jpeg); 
     inline2.ContentId = "3"; 
     inline2.TransferEncoding = System.Net.Mime.TransferEncoding.Base64; 
     avHtml.LinkedResources.Add(inline2); 

     LinkedResource inline3 = new LinkedResource(System.Web.HttpContext.Current.Server.MapPath("~/Content/Images/4.jpg"), MediaTypeNames.Image.Jpeg); 
     inline3.ContentId = "4"; 
     inline3.TransferEncoding = System.Net.Mime.TransferEncoding.Base64; 
     avHtml.LinkedResources.Add(inline3); 

     MailMessage mail = new MailMessage(); 
     mail.AlternateViews.Add(avHtml); 

HTML:

 <img src="cid:1" alt="" /> 
     <img src="cid:2" alt="" /> 
     <img src="cid:3" alt="" /` 
     <img src="cid:4" alt="" /> 
相关问题