0

Hi We are trying to develop a mail sending system using MailKit. We have a set of Email Templates which are created using WORD and saved as MHTML files. The whole thing is working fine, when we use MailKit to create a MimeMessage from the MHT file.

But post creating this message, I am not able to see a way of adding attachments to this.

Currently we are trying the following.

private void SendEmail(string templatePath, List<string> attachments)
    {
        // Load the MHT Template
        var mimeMessage = MimeMessage.Load(templatePath);

        mimeMessage.From.Add(new MailBoxAddress("test@Test.com"));
        mimeMessage.To.Add(new MailBoxAddress("test@Test.com"));

        foreach (var attachment in attachments)
        {
            var fileAttachment = new MimePart()
            {
                ContentObject = new ContentObject(File.OpenRead(Path.Combine(attachment), ContentEncoding.Default),
                ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
                ContentTransferEncoding = ContentEncoding.Binary,
                FileName = Path.GetFileName(attachment)
            };

            // Attachments is a read only Enumerable here.
            mimeMessage.Attachments.Add
        }

    }
Abhilash
  • 1
  • 1
  • 1

2 Answers2

2

You will need to traverse the MIME tree structure of the message until you find the Multipart that you would like to add the "attachment" to and then use the Multipart.Add() method.

Keep in mind that a message is a nested tree structure and not a well-defined structure which has only 1 message body (or even just 2) and a list of attachments. It's a whole lot more complicated than that, so there's literally no way for MimeMessage.Attachments to "do the right thing".

For the general case, you can probably get away with something like this:

var message = MimeMessage.Load(fileName);
var attachment = new MimePart("application", "octet-stream") {
    FileName = attachmentName,
    ContentTransferEncoding = ContentEncoding.Base64,
    Content = new MimeContent(attachmentStream)
};

if (!(message.Body is Multipart multipart &&
      multipart.ContentType.Matches("multipart", "mixed"))) {
    // The top-level MIME part is not a multipart/mixed.
    //
    // Attachments are typically added to a multipart/mixed
    // container which tends to be the top-level MIME part
    // of the message (unless it is signed or encrypted).
    //
    // If the message is signed or encrypted, though, we do
    // do not want to mess with the structure, so the correct
    // thing to do there is to encapsulate the top-level part
    // in a multipart/mixed just like we are going to do anyway.
    multipart = new Multipart("mixed");

    // Replace the message body with the multipart/mixed and
    // add the old message body to it.
    multipart.Add(message.Body);
    message.Body = multipart;
}

// Add the attachment.
multipart.Add(attachment);

// Save the message back out to disk.
message.WriteTo(newFileName);
jstedfast
  • 35,744
  • 5
  • 97
  • 110
  • I will try this and we got it working by loading the message once from mht and adding all the body parts of the message to a multipart along with attachments and creating a new message.. However I will definitely give a try for this and let you know – Abhilash Sep 29 '17 at 17:27
  • Just curious about it: Any examples of a "non general case"? (i.e.: In what case the code above doesn't do the right thing?). BTW, I'm very grateful about your MailKit. Thanks. :-) – Yanko Hernández Alvarez Dec 26 '22 at 13:29
1

I add the attachment by the BodyBuilder:

BodyBuilder _body = new BodyBuilder
{
    HtmlBody = message
};
_body.Attachments.Add(_fileName, _stream);
_email.Body = _body.ToMessageBody();

See this post stackoverflow

Phil Huhn
  • 3,307
  • 3
  • 18
  • 35