2011-08-13 116 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="" /> 
相關問題