Image violation when sending mail using SmtpClient

I am sending mail using C # using the SmtpClient class. Before sending mail, I do the following.

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

and below is my MailService class:

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

Now, when I send mail, the mail is sent, that’s what I get as the contents of the mail in Outlook when I click the view source. Below is the content of the email with the view source (obviously, I saved only part of the image data)

 <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> 

So it looks broken (images) in the mail, but when I copy this source and paste it into the editor and open the file with a browser, everything seems good (even the images).

Update: added image mail from Outlook

enter image description here

Any ideas ????

+6
source share
2 answers

This is what I tried and works for me, tested in Outlook, Thunderbird and Gmail. HOW MUCH WORKS!

You might want to check the following resources that I referenced for this to happen:

Code example:

 // 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(" yasser@mail.yy "); mailMessage.From = new MailAddress(" info@mail.yy ", "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); 
+13
source

Here is a function that will fix the problem. Call it before sending SendEmail, for example:

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

The ProcessEmbeddingImages function is written in VB.Net, so you can translate it into C # using one of these online translators.

 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 
+2
source

Source: https://habr.com/ru/post/945787/


All Articles