Nix
Nix

Reputation: 58522

Email with embedded images showing as "Preview Document" in Outlook 2010 & 2016

We are currently sending a relatively simple email in C# via Amazon SES. For almost all clients the email looks correctly but Outlook is not showing the email but showing it as an attachment.

Email building code:

 LinkedResource logoResource = null;
 //Attach Logo 
 if (!string.IsNullOrEmpty(emailMessage.Logo))
 {
     messageHtml = messageHtml.Replace("{{Logo}}", emailMessage.Logo);
     var imageData = Convert.FromBase64String(emailMessage.Logo.Split(Convert.ToChar(","))[1]);

     logoResource = new LinkedResource(new MemoryStream(imageData))
     {
         ContentId = "logo",
         ContentType = new ContentType("image/png"),
         TransferEncoding = TransferEncoding.Base64
     };
 }
 var htmlView = AlternateView.CreateAlternateViewFromString(messageHtml, null, MediaTypeNames.Text.Html);

htmlView.LinkedResources.Add(logoResource);

var message = new MailMessage {
   IsBodyHtml = false,
   Subject = emailMessage.Subject,
   Body = string.IsNullOrEmpty(emailMessage.MessageText) ? emailMessage.Message : emailMessage.MessageText,
   From = new MailAddress(emailMessage.From)
 };

message.AlternateViews.Add(htmlView);

Template:

<tr style="margin-bottom:15px;/*logostyle*/">
    <td width="600" class="mobile" style="font-family: arial; font-size: 12px;  padding: 10px;" align="center">
    <img src="cid:logo"  style="width: 350px" />
   </td>
</tr>

Let me know if there is anything else that interest you.

outlook

Upvotes: 1

Views: 438

Answers (1)

JAZ
JAZ

Reputation: 1070

I think Outlook does not have an alternate view, that's why it does not work for it.

Small Snippet to send the mail once you create your mail message object.

RawMessage rawMessage;

using (MemoryStream memoryStream = ConvertMailMessageToMemoryStream(gMessage))
{
    rawMessage = new RawMessage(memoryStream);
}

SendRawEmailRequest request = new SendRawEmailRequest();

request.RawMessage = rawMessage;
request.Destinations.Add(MessageToSend.ToRecipient.Trim().ToLower());
request.Source = MessageToSend.SenderEmail;

var ses = new Amazon.SimpleEmail.AmazonSimpleEmailServiceClient(UserName, sMailPassword, Amazon.RegionEndpoint.USEast1);

SendRawEmailResponse response = ses.SendRawEmail(request);

Here is the ConvertMailMessageToMemoryStream that came from an Amazon Support forum .

/// <summary>
/// Converts the mail message to memory stream. https://goo.gl/TrCqBu
/// </summary>
/// <param name="message">The message.</param>
/// <returns>MemoryStream.</returns>
public static MemoryStream ConvertMailMessageToMemoryStream(MailMessage message)
{
    Assembly assembly = typeof(SmtpClient).Assembly;
    Type mailWriterType = assembly.GetType("System.Net.Mail.MailWriter");
    MemoryStream fileStream = new MemoryStream();
    ConstructorInfo mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null);
    object mailWriter = mailWriterContructor.Invoke(new object[] { fileStream });
    MethodInfo sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic);

    if (sendMethod.GetParameters().Length == 2)
        sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true }, null);
    else
        sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true, true }, null);

    MethodInfo closeMethod = mailWriter.GetType().GetMethod("Close", BindingFlags.Instance | BindingFlags.NonPublic);
    closeMethod.Invoke(mailWriter, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { }, null);
    return fileStream;
}

Upvotes: 1

Related Questions