Introduction

I needed a POP3 library for a .NET project that a friend and I were working
on, and while a quick Google-search revealed several free implementations, none
of them fully fit my requirements. I wanted a reliable POP3 class with full
support for asynchronous fetching, cancellation, SSL, attachments, HTML email, and an uncomplicated and simple
interface so that calling applications wouldn't need to do hideous workarounds
to integrate it into their existing system. This article explains how this
library can be used, talks about the class implementation, and also includes a
demo WPF application that shows how a typical app might use this library.
This library's goal is to provide developers with a very simple way to read
email from POP3 servers, and with that in mind, it hides the underlying POP3
protocol from calling code. What that means is that this library is not for
those who are writing their own POP3 based code or want to extend the POP3
protocol in some way (for example writing a spam filter or an email
auto-forwarding application). In some ways this library can be considered as a
POP3 analogy to the SmtpClient class from the System.Net.Mail
namespace and in fact it actually uses the MailMessage class (from
the same namespace) to represent an email (although that had its disadvantages
as I will explain in this article).

Safety note about the demo app

The PopClient class has a DeleteMailAfterPop
property that's used to specify whether mails should be left on the server or if
they should be deleted after they are fetched. Unless it's a throwaway POP
account, chances are extremely low that you'd want to delete mails when running
the demo app, and so as a precautionary measure, that property has been disabled
both in the UI and in the code, so you will not inadvertently delete any of your
email.

VS 2010 and .NET 4.0

While the code and the the demo project has been written and tested using VS
2010 and .NET 4.0, you should not have too much difficulty using this from VS
2008 and .NET 3.5. As far as I know, I have not used any 4.0 specific features
in any of the code.

Using the library

All the code is in the PopClient assembly, so you need to add a
reference to that. And all the public classes are under the
Extra.Mail namespace, so you may want to add a using
declaration in your code for that namespace. The PopClient class is
the only class that you need to directly instantiate and use, and it implements
IDisposable and it's important that you dispose it off when you are
finished with the class. That said, since the class fetches mail asynchronously,
you should not dispose off the class until either the mail fetch operation has
completed, or you have manually aborted the mail fetch operation. This basically
means that it's not the best suited class for an using-block
(typically used for IDisposable types). The demo app shows one
typical way that the class be be disposed, and I'll also discuss another simple
way to dispose off the instance safely. Ironically, after saying all this, the
first bit of code I am about to show you does use an using-block,
although this is a console application and I take precautions to ensure that the
object stays alive until the POP3 operation has completed.

The class is instantiated with the required POP3 settings such as host,
username, and password. I have also hooked onto several events which will be
fired asynchronously during the POP3 fetch operation. Once this is all done, a
call is made to the PopMail method (which immediately returns), and
it's called from a try-catch block since the method
can throw exceptions. Although the code above only catches a
PopClientException be aware that it can also throw an
InvalidOperationException (the demo app handles both). And finally notice
the crafty positioning of the Console.ReadKey call to keep the
object alive and un-disposed until the fetch is completed. The ChatXXXLog
events basically log protocol-chat used for the POP3 connection, with the
ChatCommandLog firing for all commands we send to the server and the
ChatResponseLog firing for all single-line server responses (for
usability reasons, I do not log multi-line responses, since that will quickly be
unmanageable when fetching large emails with bulky attachments). It's purely
optional to handle these events and their use is primarily to diagnose
connectivity issues, although you could also follow the chat log to get an idea
of how POP3 chat is executed (it's a very simple protocol, so it's doubtful that
anyone will want to do it for that purpose more than once or twice).

The WPF demo app shows a better way to show this information. The other three
events are what you really need to handle for reading the fetched emails. The
first one to fire will be the QueryPopInfoCompleted event, which
gives you the number of emails and their total size. You can potentially use
this information to show a progress-bar or to update a summary status UI panel.

Next, the MailPopped event fires once for each mail that's
retrieved, so if you've handled the QueryPopInfoCompleted event you
will know how many times this will fire (unless you cancel the operation with a
call to Cancel()). The Class Reference section details all the
information, arguments, and properties that are available, so I will not
explain every single item in the code, although the property names are fairly
self descriptive, so anyone writing code to fetch email probably won't need to
look at the documentation.

The MailPoppedEventArgs.Message property is of type
MailMessage, so anyone who's used that class before will recognize the
other properties that I've used there. The developers who wrote
MailMessage intended it primarily for the SmtpClient class,
which meant that it does not have certain properties that you need when you are
retrieving mail, such as Uidl, ReceivedTime,
Size etc. So I had to provide them though the MailPoppedEventArgs
class. I realized this only after I had written half the code and while it would
not have been terribly difficult to write my custom MailMessage-like
class, I decided to continue using MailMessage, largely out of my
inconsiderate need to ensure that my class remained analogous and similar to the
SmtpClient class which used MailMessage. Developers
like familiarity and I believe that using recognizable types will certainly help
with that. I also added an extension method to the Attachment class
so that you won't have to mess with memory streams and file IO, and instead can
just call a nice Save(filePath) method that will save the
attachment (the WPF demo app does make use of this). The last event that's fired
is the MailPopCompleted event. Note that this is always fired,
whether the POP fetch completed harmoniously, or if it got user cancelled, or
even if it had to abort because of an exception. In fact it's the only way to be
notified of unexpected errors, so you should always handle this event.

This code does not fully demonstrate how the PopClientException
can be used to determine POP3 errors (like a bad password, or a POP3 server
error), but the demo app does a better job with that.

Retrieving only new messages

Support for retrieving only new messages was added in
the November 19th 2010 update.

If you've noticed with mail clients that have an option to leave mail on the
server, they only retrieve mail that has not been previously fetched. They
achieve this by storing the UIDL values for each mail message and then not
downloading messages that match an existing UIDL. The PopClient
class now has a collection property called UidlsToIgnore.
So prior to calling PopMail, the calling client can
optionally populate this collection and those messages will be skipped. Changes
have been made to the library so that the count and total size reported will be
adjusted to accommodate these skipped messages. Be aware though that the index
value provided by the MailPoppedEventArgs
class will continue to represent the index value of the message in the mail
server. So you will potentially see non-contiguous indices when fetching mail if
you have opted to skip existing messages. This is not a bug and is correct
behavior. Example code showing how skip-UIDLs are added:

Warning : Event handlers and thread context

One very important thing to keep in mind is that all the events except for
the MailPopCompleted event are fired on a different thread (the
worker thread that the class internally uses for the POP3 connection). So if you
are handling UI from these event handlers, you need to take the typical
precautions that you need to take when accessing UI controls from auxiliary
threads. There are well-known methods to work around this where the events can
be made to fire on the same thread that created the PopClient
object, but I decided not to go that route for two specific reasons. The first
reason is that this forces the PopClient class to be aware of such
UI/threading issues and I wanted to keep the class design clean which meant that
it had to be kept unaware of such frivolous side effects. A second important
reason is that whether the calling code uses Windows Forms or WPF would dictate
the need to handle thread context in distinct ways, not to mention that the
class may be used from other .NET UI frameworks which may have their own thread
related quirks. A third minor reason is that it may actually be a hazardous
approach to hide this from the caller by attempting to handle this in the
PopClient class, since the caller will remain blissfully unaware of these
threading issues and will thus be unprepared to deal with any potential
consequences arising out of inter-thread access. And finally, as you will see
from the demo project, it's quite trivial to handle this in the calling UI code.

The demo application

Figure 4 - Saving an attachment

Figure 5 - Detailed logging/exception handling

The WPF demo application was written using Visual Studio 2010 and targets the
.NET 4.0 framework. I will completely refrain from discussing the XAML code here
and will instead focus on how the PopClient class is typically used
in a UI application. Those of you who are interested in the XAML/data-binding
can go through the project source, and if you have specific questions (unlikely
given how simple the code is), please feel free to ask me through the forum for
this article. The demo project uses MVVM and all of the PopClient
code is in a single View-Model class. Every method that I discuss below will
thus be a part of this class.

The View-Model has a PopClient field (needs to be a field, so we
can support cancellation and disposing). Note that the socket connection is not
established when you instantiate the class (not surprising since it does not
have connection info yet).

In addition, I also handle the application's Exit event so I can
dispose off the popClient instance. Technically this can be
considered a superficial thing to do since the process will have terminated and
all process-specific resources would be released. But it keeps the code clean
and encourages this practice in applications where the V-M may be created and
destroyed multiple times during the life of an application (in which case, the
V-M itself should probably be an IDisposable). It's a little easier
with WinForms since all Controls and Forms are
IDisposable, and thus there's a documented well-established place to
dispose the PopClient instance. WPF windows don't do it that way,
since the WPF approach of using weak references everywhere makes this
unnecessary. One alternate way to dispose off the PopClient
instance is in the MailPopCompleted event handler although it is
not a very clean approach and is a bit of a hack. I say that because when the
event fires, the PopClient instance is still in use, so for a few
microseconds you actually have a disposed object that's still executing a method
(albeit its last one). Of course since I wrote the class, I know it's safe to do
this (as of today) and there's no risk of the GC firing when it's still not done
executing a method, but if you run code profilers or memory leak analyzers, they
may complain and throw up an agitated warning message. So I wouldn't recommend
doing this unless it's in code that you are in full control of.

The following fields are used to propagate information to the UI, namely the
main window and the log window. The LogInfo class is merely a
convenience class I created to help with data-binding. One
important member here is the mainDispatcher field which is used to
handle the thread context issues arising from how the events are fired on
secondary threads (and not from the main UI thread where the handlers were
originally setup from).

Notice how CanRefresh delegates the call to
PopClient.IsWorking which will return true if a fetch
operation is current under way. I assign the various POP3 properties that are
required for a POP3 connection here, although for this particular demo project
this was actually a mistake to do this here - since it gets called every time
Refresh is called. Originally I had planned to allow the user to
change POP settings after a fetch, but eventually I ended up showing the
settings dialog only once, at startup. Of course that's a rather insignificant
issue, but I thought I'd mention that here in case someone wonders why I did it
that way. Notice how I save the current Dispatcher instance in the
mainDispatcher field, this is what I'll use later to update my
ObservableCollection<>s because they will be bound to the View and
will thus need to execute on the UI thread.

There is a potential race condition where CanCancel returns
true, but the fetch operation completes before Cancel
is called. But it's safe to call Cancel even in that scenario, so
there's no need to handle that race condition.

Here's the code that's used to save an attachment (this is accessible via the
context menu on attachment icons).

The code here is a better example of how the various exceptions are handled
(compared to the code I showed earlier). It demonstrates how the application can
handle POP3 server errors and display those messages back to the user.

Implementation details

One of the design intentions was to hide the implementation details from the
public interface and this meant that I could opt to selectively implement the
minimal protocol needed to fetch email from a POP3 server without losing out on
any POP3 functionality. The internal class PopConnection
is used to establish a socket connection and to send/receive POP3 commands and
responses from a server. It's a very thin socket based class that uses a
TcpClient object to communicate with a POP server.

Derived classes now just need to implement ExecuteInternal and
optionally ParseInternal (if they need to parse the response
stream). Here's how the User command is implemented, it's one of
the more simple ones as it does not do custom parsing on the response.

Notice the use of the CDOMessageConverter class. CDO
(Collaboration Data Objects) is a COM component that's been part of Windows OSes
since Windows 2000, and it has built in functionality to parse MIME based email
(including full support for attachments). CDO has no idea about the
MailMessage class, so I wrote a converter that will take a MIME string,
construct a CDO message from it, and then convert the CDO message into a
MailMessage object. It's fairly straightforward COM-interop, so I won't
go into the details. The two classes do not have a one-to-one structural
equivalence, so I had to make certain compromises, but as long as I was able to
obtain all fields required to read an email message with attachments, I was not
too concerned about superficial differences between the types.

The PopChat class provides a single point interface from where
the PopClient class can invoke POP commands. Here's a snipped code
listing that shows what the class does. In addition to exposing properties for
each command, it also makes sure that all commands have their log events
subscribed to via a common event handler.

Conclusion

If you run into specific issues with a POP server, the chat log (easily
accessible via the event handlers) should tell you exactly what's going on. As
always, feedback and criticism is welcome, and please feel free to post your
comments through the discussion forum for this article. Although if you post
something nasty or vote anything less than a 5, I have a Yaqui curse that
I recently learned all ready to apply on you! *grin*

History

November 8th, 2010 - Article first published.

November 19th, 2010

Default POP port was incorrectly set to the SMTP port. This is now
fixed.

Added support for skippable UIDLs. This lets you only retrieve mail that
was not fetched earlier.

New command objects added for UIDL and LIST that supplement the existing
versions, except that these do an index-less full fetch.

Share

About the Author

Nish is a real nice guy who has been writing code since 1990 when he first got his hands on an 8088 with 640 KB RAM. Originally from sunny Trivandrum in India, he has been living in various places over the past few years and often thinks it’s time he settled down somewhere.

Nish has been a Microsoft Visual C++ MVP since October, 2002 - awfully nice of Microsoft, he thinks. He maintains an MVP tips and tricks web site - www.voidnish.com where you can find a consolidated list of his articles, writings and ideas on VC++, MFC, .NET and C++/CLI. Oh, and you might want to check out his blog on C++/CLI, MFC, .NET and a lot of other stuff - blog.voidnish.com.

Comments and Discussions

Great project!
Do you happen to know how one could get ONLY the newest emails (e.g. when I store the fetched emails locally) and not all of them?
Should I fetch them in groups of 5 and then try to guess where I left of by comparing mail hash codes with the last fetched email's hash?

I have a single test email in the mailbox.
(If there are none, this does not occur.)

At line 88,

return stream.Read(bytes, 0, bufferSize);

I get "Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond."

I have not used this class in a while now, so unfortunately I am not in a position where I can debug this and figure it out. One of the disadvantages of open source code I guess - the authors may not always be able to support it.

Have you tried manually sending POP3 commands via a telnet session to this specific mail server? It may help isolate out the problem (assuming there's an issue with the server).

I apologize for what may not have been as helpful a response as you may have been hoping for.

Are you available for consultation? (for a fee of course)
I just need a bit of help to get this kick-started, I'm a home-biz lone developer trying to add some basic email capability to my commercial product.

I've been working on my project and I found out that when I connect to the server, it starts working and brings messages but it starts from the oldest to the newest.

This is a big problem because I'll have to load all messages each time I open the project and if I have a big amount of messages that'll spend a lot of time. I tried out with my mail account and having 1377 mails it spent almoust 40 minutes...

Is there a way to skip the oldest messages and just bring the newer ones?

Regarding your update:
November 19th, 2010
* Added support for skippable UIDLs. This lets you only retrieve mail that was not fetched
earlier.

I downloaded the source code and try to use it. It has been a big help to use your program.
Can you upload again your latest code with updates on "Added support for skippable UIDLs"."PopClient" has no method for "skippable UIDLs - popClient.UidlsToIgnore.Add", inorder to implement:
popClient.UidlsToIgnore.Add("717619000000008003"); I would appreciate if you can upload your latest source code with the new feature. Thanks in advance.