2011-08-13 3 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> 

그래서 질문이 아닌 첨부 파일로, HTML 본문에 여러 개의 이미지를 전송하는 방법입니다.

+1

[C#에서 본문에 포함 된 이미지가 포함 된 전자 메일 보내기] 가능한 복제본 (http://stackoverflow.com/questions/1921275/sending-an-email-with-an-image-embedded-in-the- body-from-c) –

답변

6

에 관심이있을 수 있습니다 그래서 제 1 회 한 다음 하나를 무시하고 그래서 텍스트 만보고 이미지가 첨부 파일로 전송됩니다

나는 다음과 같은 변화를 만들어 그것을

AlternateView avText = AlternateView.CreateAlternateViewFromString(metric.Name, null, **MediaTypeNames.Text.Plain**); 
AlternateView avImages = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html); 
을 예상대로 일
+0

정확한 문제가있었습니다. 이것은 내가 찾고 있었던 바로 그 것이었다! 그러나 2 개 이상의 이미지를 사용하게되면 각 AlternateView를 작성하는 방법을 완전히 알지 못합니다. 나는 모두를 만들 수 있지만 텍스트로 마지막 만들 수 있다고 가정합니다 .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-- 

당신은 대신 콘텐츠 ID의 LinkedResource.ContentLink property을 할당해야합니다.

두 번째 두번째 이미지는 the "data" URL scheme으로 html에 직접 삽입 할 수 있습니다.

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

알아두면, 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); 

당신이 볼 수 있듯이, 모두 내 뷰 Text.Html로 지정되어있는 그것을 무엇인지 파악 생각, 그래서 “foreach” vs “ForEach”

+0

어떻게 (html) 잘 형성되지 않습니까? 설명 할 수 있니? – user330612

+0

내 pblm에 대한 해결책을 찾았습니다. 아래에 말한 것처럼 – user330612

+0

임베디드 이미지에 대한 절대 URI가 내 문제를 해결했습니다. –

1

당신이 이미지를 온라인으로 가지고 있다면, 호스팅 된 사이트에서 보내는 것을 의미합니다. src에 URL을 넣는 것만으로 그 이미지를 참조하는 것이 좋습니다.

<!-- 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); 
    } 

다음으로 i를 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); 
    } 

-, 예를 들면, <img src="Images/logo_shadow.png" alt="" style="width: 100%;" /><img src="cid:logo_shadow.png" alt="" style="width: 100%;" />

다음 마지막 작업으로 HTML 본문 대체 될 것입니다 :

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); 
: 메일에 이미지 itselfs를 추가

HTML :

 <img src="cid:1" alt="" /> 
     <img src="cid:2" alt="" /> 
     <img src="cid:3" alt="" /` 
     <img src="cid:4" alt="" /> 
관련 문제