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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With