Images not embedding properly in dynamically generated email

1.3k Views Asked by At

I can't get my pictures to embed properly, when the email arrives they appear only as attachments. The "dynamic" part is that the number of pictures in an email isn't known until it's about to be sent. This is an example of what the HTML might look like before it gets sent.

<html>
<body>
<h1>LineOne</h1>
<p>LineTwo</p>
<img src='cid:1' alt='ImageOne'></img>
<img src='cid:2' alt='ImageTwo'></img>
</body>
</html>

The email arrives but only the text is shown, the images appear as attachments. If it makes any difference, I'm using LinkedResources in VB.NET. When I used the same code to send a single image (ie not dynamic), it embedded properly. I can't work out what's different this time.

EDIT: Here is my VB code, to add a bit of context.

Private Sub TimeBeforeEmailSent_Tick(sender As System.Object, e As System.EventArgs)      Handles TimeBeforeEmailSent.Tick
    Dim sendEmail As New sendEmail
    Dim image(numberOfPhotosTaken) As Object
    For i = 1 To numberOfPhotosTaken
        image(i) = New LinkedResource((Mid(Application.ExecutablePath, 1, (Application.ExecutablePath.Length - 9)) + i.ToString + ".jpg"), "image/jpeg")
    Next
    sendEmail.write(numberOfPhotosTaken, image)
    TimeBeforeEmailSent.Enabled = False
End Sub

And here is the class sendEmail:

Imports System.Net.Mail
Imports System.IO


Public Class sendEmail
Dim bodyText As String = "<html><body><h1>Heading</h1><p>Body</p>"
Dim alternateView As AlternateView = AlternateView.CreateAlternateViewFromString(bodyText, Nothing, "text/html")



Public Sub write(numberOfPhotosTaken As Integer, image As Array)
    For i = 1 To numberOfPhotosTaken
        Try
            image(i).ContentId = i
            image(i).TransferEncoding = Net.Mime.TransferEncoding.Base64
            alternateView.LinkedResources.Add(image(i))
            bodyText = bodyText & "<img src='cid:" & i & "' alt='image from webcam'></img>"
        Catch ex As Exception
            'This exception means two or more photos were taken in such quick succession that the camera couldn't keep up
            'Therefore, the program thinks more photos were taken than actually exist
        End Try
    Next
    bodyText = bodyText & "</body></html>"
    Dim Mail As New MailMessage
    Mail.Headers.Add("Content-Type", "multipart/related")
    Mail.Headers.Add("Content-Disposition", "inline")
    Mail.AlternateViews.Add(alternateView)
    Mail.Subject = "Subject"
    Mail.To.Add(Lockscreen.sendToAddress)
    Mail.From = New MailAddress(removed for privacy)
    Mail.Body = Nothing
    send(Mail)
End Sub


Sub send(Mail)
    Dim SMTP As New SmtpClient
    SMTP.EnableSsl = True
    SMTP.Credentials = New System.Net.NetworkCredential(removed for privacy)
    SMTP.Port = "587"
    SMTP.Host = "smtp.gmail.com"
    SMTP.Send(Mail)
    Dim filePath As String
    For i = 1 To Lockscreen.numberOfPhotosTaken
        Try
            filePath = (Mid(Application.ExecutablePath, 1, (Application.ExecutablePath.Length - 9)) + i.ToString + ".jpg")
            File.Delete(filePath)
        Catch ex As Exception
        End Try
    Next
End Sub

End Class

1

There are 1 best solutions below

4
On

You didn't add the code where you construct and add the LinkedResource to the mail, but make sure that:

  1. When you construct the LinkedResource, make sure you use the constructor where you can pass in the correct ContentType of the image

  2. Add 2 headers to the MailMessage object:

    _mail.Headers.Add("Content-Type", "multipart/related")

    _mail.Headers.Add("Content-Disposition", "inline")