exchangewebservicesemail-attachmentssmtpclientmemorystreammailmessage

Unable to render the Exchange Email attachment properly after adding as MailAttachment for smtp


I needed to convert an EmailMessage to MailMessage for smtp mail sending. Although if the attachments are files such as .docx, .txt, .jpg etc it displays correctly. The problem I'm facing is that whenever the EmailMessage contains email attachments (.msg), the attachment become strings /stream(Image2). I have added a screenshot of the properties of the attachment object(Image3).

Question: What do I need to add in my code to make sure that the attachment is exactly similar from the original attachment coming from Microsoft Exchange Email like for example the expected result Image1?

Image1: How the attachment should look like after smtp send. Before the attachment was sent via smtp

Image2: Result of the Attachment after smtp mail sending. Email Attachment in binaries

Image3: attachment properties screenshot Attachment Properties

My Code Below:

MailMessage message = new MailMessage();
EmailMessage msg = new EmailMessage(service); //service is Microsoft.Exchange.WebServices.Data
MemoryStream ms = new MemoryStream();
            
PropertySet propSet = new PropertySet(BasePropertySet.FirstClassProperties,ItemSchema.Attachments, EmailMessageSchema.NormalizedBody, EmailMessageSchema.TextBody);
propSet.RequestedBodyType = BodyType.HTML;
propSet.BlockExternalImages = false;
msg = EmailMessage.Bind(service, emailId, propSet);

foreach (Microsoft.Exchange.WebServices.Data.Attachment attachment in msg.Attachments){  
    if (attachment is FileAttachment)
    {
        // Attachments such as .txt, .docx, .xlsx
        // This code block for FileAttachment is totally working fine.
        FileAttachment fileAttachment = attachment as FileAttachment;
        if (fileAttachment != null)
        {
            fileAttachment.Load();
            ms = new MemoryStream(fileAttachment.Content);
            attachmentName = fileAttachment.Name;
            System.Net.Mail.Attachment att = new System.Net.Mail.Attachment(ms, attachmentName);
            message.Attachments.Add(att);
        }
    }
    else if (attachment is ItemAttachment)
    {
        //This is where the EmailMessage attachment gets converted to MailMessage attachment
        //Attachment is .msg
        //The result here becomes random strings
        ItemAttachment itemAttachment = attachment as ItemAttachment;
        if (itemAttachment != null)
        {
             itemAttachment.Load(new PropertySet(ItemSchema.MimeContent));
             byte[] itemContent = itemAttachment.Item.MimeContent.Content.ToArray();
             ms = new MemoryStream(itemContent);
             attachmentName = itemAttachment.Name;
             System.Net.Mail.Attachment att = new System.Net.Mail.Attachment(ms, attachmentName, attachment.ContentType);
             message.Attachments.Add(att);
        }
    }
}

//Send the MailMessage using SMTP
using (SmtpClient client = new SmtpClient())
{
    client.Host = config.smtp_AmazonAWSHost;
    client.Port = config.portSMTP;
    client.UseDefaultCredentials = false;
    client.Credentials = new NetworkCredential(config.smtp_Username, config.smtp_Password);
    client.EnableSsl = true;
    client.Send(message);
}

Solution

  • As the ContentType message/rfc822 indicates the message (attachment) is in the internet-message-format which is the format how mailservers usually send and receive emails, you need to change the attachments name from .msg to .eml. Outlook can easily open eml files.

    See also: saving-an-email-to-a-msg-file-using-ews-managed-api