Search code examples
c#htmlemailsmtpclient

Images breaking when sending mail using SmtpClient


I am sending a mail using C# using the SmtpClient class. I am doing the following things before sending the mail.

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 the mail, the mail gets sent, here is what I get as the content of the mail in outlook when I press the view source. Below is the content of the email with view source (Obviously I have kept only a 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 this appears broken(the images) in the mail, but when I copy this source and paste it into an editor and open the file using a browser all seems good (even the images).

Update : Added image of the mail from outlook

enter image description here

Any ideas ????


Solution

  • This is what I tried and works for me, tested in outlook, thunderbird and gmail. WORKS FINE !

    You might want to check out the following resources I referred to make this happen :

    Sample Code :

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