Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mimekit/mailkit download message body?

I have been making my own mail client recently and added a receive option, I used mimekit and mailkit as plugins and was able to download most of my mails with a reader that is supposed to show content(right now it shows subject, to, from, date)

The way I downloaded the subject, to, ... is msg.envelope.subject, msg.envelope.to But I cannot download the body like this :( when doing either msg.body, msg.textbody, msg.bodyparts, ... they all result in NOTHING, the place where it should be is just empty, I can't get it downloaded :(

Can anyone help me?

like image 943
user265889 Avatar asked Sep 11 '15 18:09

user265889


1 Answers

There are 2 ways to get the message body:

1. Download the Whole Message

This method is probably the easiest way.

To do this, all you need to do is call:

var message = folder.GetMessage (uid);

or

var message = folder.GetMessage (index);

I would recommend always using the UniqueId of the message. Since you are already using the Fetch method, all you need to do to make sure that you have the UniqueId of the message is to include the MessageSummaryItems.UniqueId in your fetch request:

var messages = folder.Fetch (0, -1, MessageSummaryItems.UniqueId |
    MessageSummaryItems.Envelope | ...);

Once you have the message, you can do whatever you want with it.

For rendering the message, I would recommend taking a look at the MessageReader sample included in the MimeKit GitHub repository.

It will show you how to properly render a MimeMessage.

2. Download Only What You Need

This method is a bit harder but can be more efficient as far as network bandwidth usage goes.

The first thing you need to do is to make sure to include the MessageSummaryItems.BodyStructure bit flag in the Fetch method. For example:

var messages = folder.Fetch (0, -1, MessageSummaryItems.Envelope | 
    MessageSummaryItems.BodyStructure);

(You'll probably want other fields, but that's just an example to show you how to bitwise-or flags together to request multiple message summary items).

By requesting the BodyStructure of the messages, you'll be able to make use of the msg.Body property.

Each msg.Body will be a BodyPart object which is an abstract class. The 2 main subclasses are BodyPartMultipart and BodyPartBasic. You can use the as cast or the is keyword to figure out which one it is:

var multipart = msg.Body as BodyPartMultipart;

if (multipart != null) {
    // the top-level body part is a multi-part
} else {
    // the body is a basic singleton part
}

This is how you would iterate over the subparts of a BodyPartMultipart:

foreach (var part in multipart.BodyParts) {
    // each part will either be a BodyPartMultipart
    // or a BodyPartBasic, just like before...
}

There are also 2 subclasses of BodyPartBasic which are: BodyPartText and BodyPartMessage. A BodyPartText is a textual-based MIME part (meaning it has a MIME-type of text/*) whereas a BodyPartMessage is an embedded message (and will have a MIME-type of message/rfc822).

Since MIME is recursive, you'll need to implement a recursive function to walk the MIME tree structure to find whatever MIME part you are looking for.

For your convenience, the TextBody and HtmlBody properties on the IMessageSummary interface will locate and return the text/plain and text/html body parts, respectively.

It should be noted, however, that these properties only work in cases where the structure of the message follows the standard convention (notice I said convention, there is no formal standard dictating the location of the message text within a MIME hierarchy).

It should also be noted that if your mail client will be rendering the HTML body, the HTML body part may be part of a group of related MIME parts (i.e. a child of a multipart/related), but the HtmlBody property will not be able to return that and so implementing your own recursive logic will be a better option.

For an example of how to do this, check out the ImapClientDemo sample in the MailKit GitHub repository. The logic currently resides in the MainWindow.cs code.

like image 138
jstedfast Avatar answered Sep 23 '22 17:09

jstedfast