Search The ForumSearch   RegisterRegister  LoginLogin

MailBee.NET IMAP

 AfterLogic Forum : MailBee.NET IMAP
Subject Topic: Downloading IMAP Emails - best practice? Post ReplyPost New Topic
Author
Message << Prev Topic | Next Topic >>
hmuscroft
Groupie
Groupie


Joined: 29 December 2009
Location: United Kingdom
Online Status: Offline
Posts: 72
Posted: 25 October 2016 at 5:50am | IP Logged Quote hmuscroft

Hi - a couple of years of ago I implemented a full email client into our software (C# WinForms) using your SMTP and POP components.

I'm now adding IMAP functionality. My goal is to approximate how Mozilla Thunderbird works with IMAP.

At the moment, I'm trying to find out the "best practice" for retrieving emails from IMAP.

As far as I can see, there are three routines for retrieving emails :-
- DownloadEnvelopes
- DownloadMessageHeaders
- DownloadEntireMessages

Do you have any guidelines/documention as to which method to use and also any suggestions for offline caching of emails when using the IMAP protocol?

Many thanks!

Kind Regards,

Hedley Muscroft
Back to Top View hmuscroft's Profile Search for other posts by hmuscroft
 
Igor
AfterLogic Support
AfterLogic Support


Joined: 24 June 2008
Location: United States
Online Status: Offline
Posts: 6038
Posted: 25 October 2016 at 6:53am | IP Logged Quote Igor

Out of the methods you mentioned, DownloadEnvelopes is the most universal one. Depending on parameters you supply, it can be used for fetching message flags, headers, message preview text, full message body, or any combination of those, see EnvelopeParts description for more info on available parts to download. Other methods listed are basically wrappers for DownloadEnvelopes used to download either just headers or full message bodies. One of the most typical approaches assumes that you download message headers (plus maybe flags and body preview additionally) to store message list in the database, and once you need to fetch the actual message, use DownloadEntireMessages for that.

Hope this helps.

--
Regards,
Igor, AfterLogic Support
Back to Top View Igor's Profile Search for other posts by Igor
 
hmuscroft
Groupie
Groupie


Joined: 29 December 2009
Location: United Kingdom
Online Status: Offline
Posts: 72
Posted: 25 October 2016 at 7:11am | IP Logged Quote hmuscroft

That's really useful - thanks for the quick response.

Once I have the Envelope objects retrieved from...

Code:
m_imap.DownloadEnvelopes(UIDs, true, EnvelopeParts.All, -2);


...please can you tell me how to determine if it has an attachment? I can't seem to find that property.
Back to Top View hmuscroft's Profile Search for other posts by hmuscroft
 
Igor
AfterLogic Support
AfterLogic Support


Joined: 24 June 2008
Location: United States
Online Status: Offline
Posts: 6038
Posted: 25 October 2016 at 7:29am | IP Logged Quote Igor

That method would download collection of entire messages including attachments, you can access each of the messages via Envelope.MessagePreview property. You are looking for HasAttachments property of that message, and Attachments would let you access the attachments themselves; you can find an example here.

--
Regards,
Igor, AfterLogic Support
Back to Top View Igor's Profile Search for other posts by Igor
 
hmuscroft
Groupie
Groupie


Joined: 29 December 2009
Location: United Kingdom
Online Status: Offline
Posts: 72
Posted: 26 October 2016 at 6:50am | IP Logged Quote hmuscroft

Thanks for your continued help. I just re-read all the documentation and realised that the -2 is a 'magic value' for downloading the entire message but not setting the SEEN flag.

What I really want to be doing with my "DownloadEnvelopes" call is just getting the basic email details (to be cached locally) and then calling "DownloadEntireMessages" to get the full message.

I've adjusted call as follows :-

Code:
m_imap.DownloadEnvelopes(UIDs, true, EnvelopeParts.MailBeeEnvelope | EnvelopeParts.MessagePreview, 0);


...and the good news that this is MUCH faster - which is what I wanted. However, I can no longer get the attachment count from 'anEnvelope.MessagePreview.Attachments.Count' as it always returns 0.

Please can you advise on how to get the attachment count while still downloading just the basic email data?

Many thanks!
Back to Top View hmuscroft's Profile Search for other posts by hmuscroft
 
Igor
AfterLogic Support
AfterLogic Support


Joined: 24 June 2008
Location: United States
Online Status: Offline
Posts: 6038
Posted: 26 October 2016 at 7:04am | IP Logged Quote Igor

Usually, if you aren't downloading an entire message and getting just the headers, there is no accurate way to get attachments count. But if you deal with IMAP envelopes, there's still a way - you need to work with EnvelopeParts.BodyStructure, a sample for that is found on ImapMail.Envelope documentation page.

On an unrelated note, there's no need to supply EnvelopeParts.MessagePreview in the method call if bodyPreviewSize is set to 0, as that means getting just the headers.

--
Regards,
Igor, AfterLogic Support
Back to Top View Igor's Profile Search for other posts by Igor
 
hmuscroft
Groupie
Groupie


Joined: 29 December 2009
Location: United Kingdom
Online Status: Offline
Posts: 72
Posted: 28 October 2016 at 3:27am | IP Logged Quote hmuscroft

This is all working beautifully - thanks for the excellent support

I'm sure there'll be more questions from me in the future!
Back to Top View hmuscroft's Profile Search for other posts by hmuscroft
 
hmuscroft
Groupie
Groupie


Joined: 29 December 2009
Location: United Kingdom
Online Status: Offline
Posts: 72
Posted: 22 February 2017 at 8:20am | IP Logged Quote hmuscroft

I'm just re-visiting the question: what is the best way to get the attachment count from an Envelope?

You kindly gave me a link to this page which provides an example.

Based on that example, my code looks like this :-

Code:

int att_count = 0;
foreach (MailBee.ImapMail.ImapBodyStructure part in env.BodyStructure.GetAllParts())
{
  // Detect if this part is attachment...
  if ((part.Disposition != null && part.Disposition.ToLower() == "attachment") ||
      (part.Filename != null && part.Filename != string.Empty) ||
      (part.ContentType != null && part.ContentType.ToLower() == "message/rfc822"))
  {
    att_count++;
  }
}


So the problem with this is that it seems to be counting "inline" attachments as well as some of the weirder attachments like "winmail.dat" which sometimes show up in emails.

Once I've downloaded the entire email, I have no problem calculating the number of attachments like this :-

Code:

static public int GetAttachmentCount(MailMessage aMsg)
{
  int res = 0;
  foreach (Attachment att in aMsg.Attachments)
    if (!att.IsInline && !IgnoreAttachment(att.Filename))
      res++;
  return res;
}
static public bool IgnoreAttachment(string AttName)
{
  return (String.Compare(AttName, "richbody.rtf", true) == 0 || String.Compare(AttName, "winmail.dat", true) == 0);
}


So the question is... is there any why I can increase the accuracy of the first block of code (i.e. when getting the attachment count from the Envelope), so that it's consistent with the second block of code?

Kind Regards,

Hedley

PS: Many thanks for you continued (superb) support. Hopefully the questions and code snippets I'm posting on this forum are also helpful to other customers!
Back to Top View hmuscroft's Profile Search for other posts by hmuscroft
 
Alex
AfterLogic Support
AfterLogic Support
Avatar

Joined: 19 November 2003
Online Status: Offline
Posts: 2206
Posted: 22 February 2017 at 8:36am | IP Logged Quote Alex

Treating whether an item is attachment or not is quite subjective. We just provided one "view" but you can have another. There is no "right" or "wrong" way to go. Your code is fine for some purposes and won't work for others.

For instance, you call winmail.dat "weird" but for someone else it can be fine. Inline attachments are also "blurry". For example, PDF file can be contained as inline attachment but it cannot often be displayed this way (it's not an image). So it can be neither attachment nor inline, and it's up to you to decide to which basket to put it.

From MIME, everything which has part.Disposition.ToLower=="attachment" (or attachment.AsMimePart.Disposition.ToLower=="attachment" equivalent for the second block) is attachment. Everything else is not. So if you need some rule, that's it. In real life, things can be more complex (like with winmail.dat) but again, it's the matter beyond the standard and it's up to your vision how to deal with them.

Regards,
Alex
Back to Top View Alex's Profile Search for other posts by Alex
 
hmuscroft
Groupie
Groupie


Joined: 29 December 2009
Location: United Kingdom
Online Status: Offline
Posts: 72
Posted: 22 February 2017 at 8:55am | IP Logged Quote hmuscroft

OK - thanks for the detailed response. Is the an equivalent to "Attachment.IsInline" when looking at the Envelope parts?
Back to Top View hmuscroft's Profile Search for other posts by hmuscroft
 
Alex
AfterLogic Support
AfterLogic Support
Avatar

Joined: 19 November 2003
Online Status: Offline
Posts: 2206
Posted: 23 February 2017 at 3:02pm | IP Logged Quote Alex

I believe it's something like

Code:
if (part.Disposition == null || part.Disposition.ToLower() != "attachment")


part is ImapBodyStructure

Regards,
Alex
Back to Top View Alex's Profile Search for other posts by Alex
 

If you wish to post a reply to this topic you must first login
If you are not already registered you must first register

  Post ReplyPost New Topic
Printable version Printable version

Forum Jump

Powered by Web Wiz Forums version 7.9
Copyright ©2001-2004 Web Wiz Guide