2013-05-24 9 views
6

Wysyłam wiadomość przy użyciu C# przy użyciu klasy SmtpClient. Robię następujące rzeczy przed wysłaniem wiadomości.Obrazy zerwania podczas wysyłania poczty za pomocą SmtpClient

var mailMessage = new MailMessage(); 

model.ToAddresses.ForEach(to => mailMessage.To.Add(to)); 
mailMessage.Subject = "Test Email - By Yasser"; 

mailMessage.Body = String.Format("{0}{1}{2}", 
            "<html><body>", 
            GetEmailContent(model), 
            "</body></html>"); 
mailMessage.IsBodyHtml = true; 
return MailService.SendEmail(mailMessage); 

i poniżej jest moja klasa Mailservice:

public class MailService 
{ 
    public static bool SendEmail(MailMessage mailMessage) 
    { 
     var smtpClient = new SmtpClient(); 
     try 
     { 
      smtpClient.Send(mailMessage); 
      return true; 
     } 
     catch(Exception exp) 
     { 
      return false; 
     } 
    } 
} 

Teraz kiedy wysłać pocztę, poczta zostanie wysłana, oto co mi się jako zawartość poczty w programie Outlook po naciśnięciu Pokaż źródło. Poniżej znajduje się treść wiadomości e-mail z widokiem na źródło (Oczywiście ja zachowałem tylko część danych obrazu) Wygląda więc na to

<html> 

<body> 
    <h1>Test</h1> 
    <h2>Hello World</h2> 
    <h3>Missing close h3 tag</h3> 

    <p> 
     <a href="www.google.com"> 
      <img src="data:image/gif;base64,/9j/4AAQSkZJRgABAgEAYABgAAD/4Q8HRXhpZgAAT" /> 
     </a> 
    </p> 
</body> 

</html> 

uszkodzony (obrazy) w mailu, ale kiedy skopiować tego źródła i wklejania do edytora i otwórz plik przy użyciu przeglądarki wszystko wydaje się dobre (nawet obrazy).

Aktualizacja: Dodano obraz poczty z Outlooka

enter image description here

jakieś pomysły ????

+0

Dla wyjaśnienia: Twój problem jest, że obrazy nie ładują (widoczne) w wiadomości e-mail? Czy pokazuje ikonę, że nie można załadować obrazu? – Florian

+0

dodano zrzut ekranu – Yasser

+0

możesz spróbować wypróbować pocztę w Gmailu lub innym webmailerze. Aby sprawdzić, czy problem dotyczy wszystkich klientów pocztowych, a nie tylko dla programu Outlook. – Florian

Odpowiedz

13

To jest to, co próbowałem i działa dla mnie, testowane w programie Outlook, Thunderbird i Gmail. DZIAŁA W PORZĄDKU !

Możesz chcieć sprawdzić następujące zasoby odniosłem aby tak się stało:

Przykładowy kod:

// we need to use the prefix 'cid' in the img src value 
string emailReadyHtml = string.empty; 
emailReadyHtml += "<p>Hello World, below are two embedded images : </p>"; 
emailReadyHtml += "<img src=\"cid:yasser\" >"; 
emailReadyHtml += "<img src=\"cid:smile\" >"; 

MailMessage mailMessage = new MailMessage(); 

mailMessage.To.Add("[email protected]"); 
mailMessage.From = new MailAddress("[email protected]", "Info"); 

mailMessage.Subject = "Test Mail"; 
mailMessage.IsBodyHtml = true; 

string image1Path = HttpContext.Current.Server.MapPath("~/Content/images/yasser.jpg"); 
byte[] image2Bytes = someArrayOfByte; 

ContentType c = new ContentType("image/jpeg"); 

// create image resource from image path using LinkedResource class. 
LinkedResource linkedResource1 = new LinkedResource(imagePath); 
linkedResource1.ContentType = c ; 
linkedResource1.ContentId = "yasser"; 
linkedResource1.TransferEncoding = TransferEncoding.Base64; 

// the linked resource can be created from bytes also, which may be stored in database (which was my case) 
LinkedResource linkedResource2 = new LinkedResource(new MemoryStream(image2Bytes)); 
linkedResource2.ContentType = c; 
linkedResource2.ContentId = "smile"; 
linkedResource2.TransferEncoding = TransferEncoding.Base64; 

AlternateView alternativeView = AlternateView.CreateAlternateViewFromString(emailReadyHtml, null, MediaTypeNames.Text.Html); 

alternativeView.ContentId = "htmlView"; 
alternativeView.TransferEncoding = TransferEncoding.SevenBit; 

alternativeView.LinkedResources.Add(linkedResource1) ; 
alternativeView.LinkedResources.Add(linkedResource2); 

mailMessage.AlternateViews.Add(alternativeView); 

SmtpClient smtpClient = new SmtpClient(); 
smtpClient.Send(mailMessage); 
+0

Nigdy nie przypisujesz ciała do wiadomości e-mail. Ten kod nie działa. – AAlferez

+1

Czy wypróbowałeś kod @AAlferez? Najlepiej jest przypisać ciało, ale nie jest to wymagane. –

2

Oto funkcja, która rozwiąże problem. Nazywają go przed SendEmail lubisz:

ProcessEmbeddingImages(mailMessage); 
return MailService.SendEmail(mailMessage); 

Funkcja ProcessEmbeddingImages jest napisane w Vb.NET więc może chcesz przetłumaczyć go do C# za pomocą jednego z tych tłumaczy internetowych.

Private Sub ProcessEmbeddingImages(ByRef oMail As System.Net.Mail.MailMessage) 
    Dim oLinkedResources As New Hashtable() 
    oMail.Body = PadSrcDataImage(oMail.Body, oLinkedResources) 
    If oLinkedResources.Count > 0 Then 

     Dim oAlternateView As System.Net.Mail.AlternateView = System.Net.Mail.AlternateView.CreateAlternateViewFromString(oMail.Body, Nothing, "text/html") 
     oAlternateView.ContentId = "htmlView" 
     oAlternateView.TransferEncoding = Net.Mime.TransferEncoding.SevenBit 

     For Each oItem As DictionaryEntry In oLinkedResources 
      Dim oKey As String() = Split(oItem.Key, "-") 
      Dim i As Integer = oKey(0) 
      Dim sExt As String = oKey(1) 
      Dim sData As String = oItem.Value 

      Dim oLinkedResource As New System.Net.Mail.LinkedResource(New IO.MemoryStream(System.Convert.FromBase64String(sData))) 
      oLinkedResource.ContentId = "MyImg" & i 
      oLinkedResource.TransferEncoding = Net.Mime.TransferEncoding.Base64 
      oLinkedResource.ContentType = New System.Net.Mime.ContentType("image/" & sExt) 
      oAlternateView.LinkedResources.Add(oLinkedResource) 
     Next 

     oMail.AlternateViews.Add(oAlternateView) 
    End If 
End Sub 

Private Function PadSrcDataImage(ByVal sHtml As String, ByRef oLinkedResources As Hashtable) As String 

    Dim oList As New ArrayList 
    Dim sSearch As String = "\ssrc=['""]data:image/(.*?);base64,(.*?)['""]" 

    Dim oMatches As System.Text.RegularExpressions.MatchCollection = System.Text.RegularExpressions.Regex.Matches(sHtml, sSearch, System.Text.RegularExpressions.RegexOptions.IgnoreCase) 
    For Each m As System.Text.RegularExpressions.Match In oMatches 
     If m.Groups.Count >= 2 Then 
      Dim sExt As String = m.Groups(1).Value 
      Dim sData As String = m.Groups(2).Value 

      If sData.Length > 7 AndAlso Right(sData, 6) = "%3D%3D" Then 
       'Replace trailing %3D%3D with == 
       sData = Left(sData, sData.Length - 6) & "==" 
      End If 

      oLinkedResources.Add(oLinkedResources.Count & "-" & sExt, sData) 

      Dim iPos1 As Integer = m.Groups(1).Index - "data:image/".Length 
      Dim iPos2 As Integer = m.Groups(2).Index + m.Groups(2).Length 
      Dim iPoints As Integer() = {iPos1, iPos2} 
      oList.Add(iPoints) 
     End If 
    Next 

    Dim sRet As String = "" 

    If oList.Count = 1 Then 'One img 
     Dim iPoints As Integer() = oList(0) 
     Dim sStr1 As String = sHtml.Substring(0, iPoints(0)) 
     Dim sStr2 As String = sHtml.Substring(iPoints(1)) 
     sRet = sStr1 & "cid:MyImg0" & sStr2 

    ElseIf oList.Count > 1 Then 

     For i As Integer = 0 To oList.Count - 1 
      Dim iPoints As Integer() = oList(i) 
      Dim iPos1 As Integer = iPoints(0) 

      If i = 0 Then 
       'First img 
       Dim sStr1 As String = sHtml.Substring(0, iPos1) 
       sRet += sStr1 & "cid:MyImg" & i 

      Else 'Rest imgs 
       Dim iPrevPos2 As Integer = oList(i - 1)(1) 
       Dim sStr1 As String = sHtml.Substring(iPrevPos2, iPos1 - iPrevPos2) 
       sRet += sStr1 & "cid:MyImg" & i 

       If i = oList.Count - 1 Then 'Last 
        sRet += sHtml.Substring(iPoints(1)) 
       End If 
      End If 
     Next 
    End If 

    If sRet <> "" Then 
     Return sRet 
    Else 
     Return sHtml 
    End If 
End Function 
+0

Co ta funkcja ma? proszę udostępnić więcej szczegółów ... – Ron

+0

Czyta dane: dane obrazu i dodaje te obrazy jako zasoby połączone. –

Powiązane problemy