简体   繁体   中英

How to make outlook mail attachment from memory?

Adding new System.Net.Mail.Attachment to Outlook.MailItem.Attachments via Attachments.Add() results in an System.ArgumentException: 'Sorry, something went wrong. You may want to try again.' System.ArgumentException: 'Sorry, something went wrong. You may want to try again.'

Trying to add a JPEG image encoded in Base64 as an attachment to a mail item in Outlook. I am storing encoded image as a variable, converting it to a memory stream, then to an attachment.

public void CreateMessageWithAttachment() {
    Outlook.MailItem mailIttem = thisAddIn.Application.CreateItem(Outlook.OlItemType.olMailItem);
    string base64Attachment = "/...base64 gibberish";
    MemoryStream ms = new MemoryStream(Convert.FromBase64String(base64Attachment));
    ContentType ct = new ContentType(MediaTypeNames.Image.Jpeg);
    Attachment attachment = new Attachment(ms, ct);

    attachment.ContentDisposition.FileName = "look_at_dis.jpg";
    mailIttem.Subject = "Test e-mail message with attachment";
    mailIttem.To = "friend@company.com";
    mailIttem.Body = "This message has been generated programmatically";
    mailIttem.Attachments.Add(attachment); // This raises "Sorry..." expression
    mailIttem.Display(true);
}

Raises System.ArgumentException: 'Sorry, something went wrong. You may want to try again.' System.ArgumentException: 'Sorry, something went wrong. You may want to try again.' , which tells me nothing :-/

Official docs gave me an impression that Attachments.Add is only supposed to really work with file paths, so saving MemoryStream to a temporary file and attaching it solved the problem.

string tempFilePath = Path.GetTempPath() + "look_at_dis.jpg";
FileStream fs = new FileStream(tempFilePath, FileMode.Create);

ms.CopyTo(fs);
fs.Close();

mailIttem.Attachments.Add(tempFilePath, Outlook.OlAttachmentType.olByValue, 1, "look_at_dis.jpg");

MailItem.Attachments.Add only allows to pass a string (a fully qualified path to a file) or another Outlook item (eg MailItem ) as the parameter.

On the Extended MAPI level (C++ or Delphi only), it is only taking an IStream (you are supposed to open PR_ATTACH_DATA_BIN as IStream using IAttach::OpenProperty ). If using Redemption (I am its author) is an option, it allows to pass a url, a file name, another Outlook item, IStream or IStorage COM interface, another attachment ( Outlook.Attachment or Redemption.RDOAttachment or IAttach MAPI interface) or an array (of Variant or of byte) to RDOMail . Attachments . Add

Before you attach the memory stream to the message, I believe you must reset its position to zero:

MemoryStream ms = new MemoryStream(Convert.FromBase64String(base64Attachment));
ms.Position = 0; // important
ContentType ct = new ContentType(MediaTypeNames.Image.Jpeg);
Attachment attachment = new Attachment(ms, ct);
// etc

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM