Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C#

Building your own Mail Client using C#

Rate me:
Please Sign up or sign in to vote.
4.08/5 (9 votes)
28 Mar 2009CPOL4 min read 109.8K   89   13
This post will go with you step by step towards building your own Mail Client using C#
IMailPlus.zip

Introduction

The code here is written under the common creativity license you could download the project from the link above or clicking on the next link IMailPlus.zip It has been enspired from Rodolfo Finochietti POP3 Project I have redesigned it and implement it and added to it SSL Support and optimized the design so that you could easily add other email clients below you will find a screen shot from the created demo application

imailplusdemo

This post will go with you step by step towards building your own Mail Client using C#, First to start I'll start you need to first know the protocol you will be retrieving emails with I will discuss here the POP3 Protocol. The POP3 Protocols an application-layer Internet standard protocol along with IMAP4 they are the two most prevalent Internet standard protocols for e-mail retrieval. To understand how the protocol works lets examine a (Server - Client) communication example. First the server is waiting for connection from any client
S: <wait for connection on TCP port 110>
The Client opens a TCP Connection with the server
C: <open connection>
The Server then response with the +OK Ready State
S: +OK POP3 server ready <1123.69123552@mail.ramymostafa.com>
Then we authenticate using the username and password
C: USER username_here
S: +OK send PASS C: PASS password
S: +OK Welcome.
C: LIST
S: +OK 2 messages (320 octets)
S: 1 120
S: 2 200
S: .
C: RETR 1
S: +OK 120 octets
S: <the POP3 server sends message 1>
S: .
C: DELE 1
S: +OK message 1 deleted
C: RETR 2
S: +OK 200 octets
S: <the POP3 server sends message 2>
The QUIT command will remove retrieved messages from the server and sign off.
C: QUIT
S: +OK dewey POP3 server signing off (maildrop empty) C: <close connection>
S: <wait for next connection>

Designing the Mail Client



imailpluslibrarydiagram

Now that we know how the POP3 protocol work we could start building our Mail Client. But before that let's discuss the structure of an e-mail message.
mailmessageA mail message consists of
  • Header which includes things like
    • Mime type
    • Received Date
    • Subject
    • To
    • From
  • Body which includes the Messages
    • HTML Message
    • Text Message
So, Basically the email client should first connect to the server and then authenticate itself with the server then start to exchange the protocol messages with the server and parse the replies to extract from it the message data or the reply status itself etc..., It should be able also to retrieve the emails from the server and parse the message retrieve to extract from it the MailMessage Information.
email-clientThe EmailClient is an AbstractClass with some properties required when connecting to the server Like the server user name, password, port number, whether or not the server uses SSL or not etc. Also it has methods for connecting to the server and Executing Commands to it , Retrieving the Server Response string and Retrieving the MaiList. In order to work with the mail client you should create your a class that inherits from the EmailClient representing the MailClient Protocol In this sample I have implemented the POPEmailClient you could find it's Members below
popmailclientThe POPEmailClient overloads the Connect Method to connect with POP3 Commands also it overloads the CreateCommand Method to create POP3 Command Format using the provided command in the parameter The Disconnect Method is used to disconnect from the server and it's called if you don't want to keep a copy of your Email's on the server if you do want to keep a copy from your emails you should not call this method. The class also overrides the GetMailList Method to retrieve the Emails From the POP3 Server and Parse it to a List of POP3Messages.

Implementing the Email Client

Connect the Client To The Server using the given username, password and server it takes as parameters the Mail Server Domain Reference, The Mail Account User Name and Password.
        public override void Connect(string server, string UserName, string Password)
{
       try
       {
           if (_isConnected)
           {
               return;
           }
           if (!UseSSL)
           {
               Connect(server, PortNumber);
               string response = Response();
               if (!response.Trim().StartsWith("+OK"))
               {
                    //TODO: Raise Error Event
               }
               else
               {
                   ExecuteCommand("USER", UserName);
                   ExecuteCommand("PASS", Password);
               }
               _isConnected = true;
           }
           else
           {
               byte[] bts;
               int res;
               string responseString = "";
               ResponseList.Clear();
               Connect(server, PortNumber);
               inStream = new SslStream(this.GetStream(), false,
                  new RemoteCertificateValidationCallback(ValidateServerCertificate),
                   new LocalCertificateSelectionCallback(SelectLocalCertificate));
               inStream.AuthenticateAsClient(server);
               bts = new byte[1024];
               res = inStream.Read(bts, 0, bts.Length);
               ResponseList.Add(Encoding.ASCII.GetString(bts, 0, res));
               responseString = ExecuteCommand("USER", UserName);
               ResponseList.Add(responseString);
               responseString = ExecuteCommand("PASS", Password);
               ResponseList.Add(responseString);
               if (!responseString.Trim().StartsWith("+OK"))
               {
                   //TODO: Raise Error Event
               }
               else
                   _isConnected = true;
            }
        }
        catch (Exception ex)
        {
            //TODO: Raise Error Event
        }
}
The GetMailList Method first Execute the Command List then it Retrieves a MetaMessageInfo from the Response String here the response string is parsed to retrieve Meta Information of the emails on the server like Number of Messages, and Messages Length
 List result = new List();
 string responseString = ExecuteCommand("LIST");
MetaMessageInfo info = new MetaMessageInfo(MailClientType.POP3,responseString);
Here we make a loop to retrieve messages until we retrieve all messages using the number of messages in the POPMessage constructor it extracts all the message info from the string to fill its attributes
for (int i = 1; i <= info.NumberOfMessages; i++)
{
    responseString = ExecuteCommand("RETR", i.ToString(), true);
    POPMessage message = new POPMessage(responseString);
    message.Number = i.ToString();
    message.Retrieved = true;
    if (message.MessageBoundaryId != null)
         result.Add(message);
}
The Method that prase the response string to retrieve info from the Email is the LoadMethod
public override void Load(string messageString)
{
    string message = messageString.Replace("+OK message follows", "");
    Message = message;
    string messageIdPure = MessageBoundaryId;
    //the start of the message body starts from MessageBoundaryId ex --- ID --- Here I extract the Message body from the complete
   //response string
    int bodyIndex = message.IndexOf("--" + messageIdPure, StringComparison.CurrentCultureIgnoreCase);
    int messageLength = message.Length - bodyIndex;
    if (bodyIndex < 0)
        return;
    string bodyString = message.Substring(bodyIndex, messageLength);
    string[] splitMessageOptions = new string[1];
    splitMessageOptions[0] = "--" + messageIdPure;
    //Here I Split with the message boundary Id to seperate the Text and HTML Messages
    string[] messages = bodyString.Split(splitMessageOptions, StringSplitOptions.RemoveEmptyEntries);
    //The Get Message Body Method retrieves the HTML, and Text Messages from the messages array
    GetMessageBody(messages);
}
to extract a header property I use
_from = GetHeaderValue(EmailHeaders.From);
Where the EmailHeaders.From is an enumerator with the headers and the GetHeaderValue Method extracts the required header value from the complete message string.

IMailPlusLibrary Usage

to use the library it's simple all you need to to do is to do the below code
POPEmailClient popClient = new POPEmailClient();
popClient.UseSSL = account.UseSSL;
popClient.PortNumber = Convert.ToInt32(account.PortNumber);
popClient.Connect(account.Server, account.UserName, account.Password);
account.CurrentAccountMails = popClient.GetMailList();

Share Your Thoughts

Finally I hope that this project would be of a great help for you. Please feel free to contact me regarding anything you don't understand in the code yo will find the library code fully XML documented. Also if you have any cool ideas or updates for it please share your thoughts here.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Egypt Egypt
Fun Coder Smile | :) My Job is my Hobby Smile | :)

Comments and Discussions

 
QuestionHow Can I get the full source on this article? Pin
Alvin.You7-Oct-18 22:37
Alvin.You7-Oct-18 22:37 
QuestionIMailPlus Pin
Member 1085159428-May-14 22:47
Member 1085159428-May-14 22:47 
QuestionEmail Client Pin
tanveerfaiz15-Jan-13 1:13
tanveerfaiz15-Jan-13 1:13 
Generalwebsite is infected Pin
Wilfred Klein20-Feb-11 1:35
Wilfred Klein20-Feb-11 1:35 
GeneralAttachment Not Support...!!!!! Pin
Jitendra.Jadav22-Dec-10 20:06
Jitendra.Jadav22-Dec-10 20:06 
GeneralAttachment is not support in this? Have you any fix to it. Pin
Muhammad - Ilyas15-Nov-10 0:55
Muhammad - Ilyas15-Nov-10 0:55 
GeneralMy vote of 5 Pin
Muhammad - Ilyas15-Nov-10 0:50
Muhammad - Ilyas15-Nov-10 0:50 
QuestionHow to Read folder lik "junk" or any customized folder on mailserver? Pin
jymitra19-Jul-10 21:47
jymitra19-Jul-10 21:47 
GeneralAttachments Pin
panast27-Jun-10 23:58
panast27-Jun-10 23:58 
Generalhotmail Pin
Member 473915530-Mar-10 16:37
Member 473915530-Mar-10 16:37 
QuestionText Message Pin
RGDavis3962-Jun-09 4:09
RGDavis3962-Jun-09 4:09 
Hi nicely done! I have been playing around with it and have had problems with the textMessage part of the email. All of the messages are comming back with everything running together. There are no line breaks, or separation of paragraphs. Am I missing something?

Thanks!
AnswerRe: Text Message Pin
rmostafa24-Jun-09 13:00
rmostafa24-Jun-09 13:00 
General[My vote of 2] Nice article Pin
Prepare UK Test30-Mar-09 5:14
Prepare UK Test30-Mar-09 5:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.