Click here to Skip to main content
15,885,216 members
Articles / Desktop Programming / Windows Forms
Article

SMTP Mail Manager

Rate me:
Please Sign up or sign in to vote.
3.10/5 (18 votes)
26 Jul 20079 min read 58.6K   3.2K   41   9
A useful library for sending mail from your apps. Its the easiest i know off.
Screenshot - smtpmailmancode.png

The SmtpMailMan

As I was browsing the classes available under the System namespace I came across the SmtpClient class, saw its breakdown and found I could use it to send email. For ages I've thought of having a little program that could send emails from my desktop without much ado, well, I didn't get anything small enough. So I decided to see what I could come up with using this SmtpClient class I just found. I never got around to write that program because some other idea came to me that I really had to pursue.

That idea was to write a program that could attach and send files to an email ( I wish I could put that program up in CodeProject for everyone to benefit from - its a little handy thing). The challenges I faced while writing the program made me decide to write an easy to use class library that is really reusable and expandable.

SmtpMailMan, meaning Smtp Mail Manager, is a class that encompasses the classes required for you to easily and successfully send a simple email that contains an attachment to one, two, three ... (3 people not tested with the class) people from within your code, and it has removed all the other classes and stuffs you'll need to create/ initialize before you send a mail successfully using the .NET 2.0's provided classes. Another interesting thing you might find in the little class will be found in the source code where a string has to be checked for its credibility of being an acceptable email address, and ...

A Peep into the Code

The SmtpMailMan library exposes two main classes; the SmtpMailMan and the MailSentEventArgs classes. I will only discuss on the SmtpMailMan class in this article.

Here is a list of the main classes in the .Net 2.0 that were used in SmtpMailMan;

  • SmtpClient
  • MailMessage
  • MailAddress
  • NetworkCredential

A summarized explanation of these class and their application in the SmtpMailMan class will be sufficient to accomplish our "peep into the code".

MailAddress

First you shouldn't worry about why this has to be the first class that I'll explain, just follow me as I lead you onto the edge for a peep.

If you'd successfully send an email then the email must have a destination - or you'll end up blowing it into the open air and have blown straight back into your face. The MailMessage class needs a credible mail address for it to do its work, credible in the sense that it only has to be an address that conforms to the acceptable format of an email address - it doesn't have to actually exist, though if you're serious about sending a mail you'll feed it with a valid email. MailMessage will not take a raw string from you to use in any of its destination fields - except you access the inner methods, what it accepts in its To, Cc and Bcc properties is a MailAddress object. Getting the email string from the user and then converting to the MailAddress object might be clumsy ( and it truly is when you consider the other conversions that you'll have to make), so I decided to beat this in my own class by doing the job for you. When you assign a string email to the To property that I exposed in the my class (SmtpMailMan), it immediately checks to see if the email is a credible one and then assign it to the MailMessge object that will carry the message you intend to send.

You might want to see the code that certifies that the email string you assigned is credible.

C#
protected bool CertifiedEmail ( string email )
      {
          Regex re = new Regex(@"\w.\w@{1,1}\w[.\w]?.\w");
          return re.IsMatch(email);
      }

I used a regular expression now, unlike in the first case, and this is reliable, you can try it out.The usage is pretty the same, I didn't change that.

C#
set
         {
             if ( CertifiedEmail( value ) )
             {
                 to = value;
                 if ( value != "" )
                 {
                     mail.To.Add( value );
                 }
             }

MailMessage

The MailMessage class is the class that handles the message that will be sent along with its attachments. The object I created for this is the mail object. This class exposes properties such as; Subject, Body, Attachments, To, Cc, Bcc. SmtpMailMan makes the job of getting all this except the Attachments done by exposing properties that you can easily set. Just appropriate string value to the appropriate property and you're done. The only Property of the MailMessage that I implemented differently is the Attachments property, which I exposed through a method. I did it this way because it is possible for you to want to add more than a file as attachment and I really want to make everything very simple and easy so instead of making it a property that you may not readily understand how to use in adding up your files for attachment I decided to use a method ( AttachFile( string path) ) that you call the number of times you want, each time with the full path of the attachment as the only argument - now there is an overload that handles multiple files passed to it as string array, isn't that nice.

NetworkCredential

A NetworkCredential object is required by the SmtpClient for it to know the email account it will pass to the SmtpServer for authentication. Authentication is required because we're connecting a server at another site for the sending of our mail.

The NetworkCredential object contains an Account property which represents the username part of an email address, and the Password property which must the correct password of the user account on the server. The Account and the Password must in turn be valid on the server. For example my email address is laolusrael@yahoo.co.uk, and my password is xxxxxxx (of course you don't expect me to tell you that). So, for a NetworkCredential object the Account would be 'laolusrael' and the Password would be set to 'xxxxxxx'.

The way I implemented this class in SmtpMailMan is such that you wouldn't even know there was such a class as NetworkCredential, all you do is assign a valid email address to the Account property of the SmtpMailMan and set the Password field to the correct password of the mail account you specified in the Account property.

SmtpClient

I would have called this the main class that made SmtpMailMan possible but because all the classes worked together to achieve SmtpMailMan and none would have worked successfully without the other. I created an object of the SmtpClient class which I called smtpClient. The smtpClient object handles the connection to the remote SMTP Server that does the sending of the mail, it exposes the following properties and methods;

  • Host
  • EnableSsl
  • Port
  • UseDefaultCredentials
  • Credentials
  • SendAsync ()

Its easy to understand, the Host property accepts a string containing the IP or url address of the SMTP Server, the Port gets the port on which the Server listens, EnableSsl is used to specify that whether the server uses SSL for its authentication or not. UseDefaultCredentials also accepts true or false that tells whether to use the system's default credentials, I read that this should be set to false - since you would be specifying the Credentials yourself. The Credential property is set to the NetworkCredential object explained above.

SendAsync() method handles the sending of the mail in asynchronous mode which is actually what you should use - there is Send(), this is because your UI does not freeze while the mail is being sent. The smtpClient object exposes an event, SendCompleted(), that gets invoked when the mail sending is complete so you'll be able to determine whether the mail was sent successfully or not. However, there is a threading error in this class somewhere when objects get passed between the application threads. I think this is more of a problem in the .Net 2.0 classes that work over the internet, while I have not yet found a clean work around for this problem, I used the BackgroundWorker class to suppress the Exception that often gets thrown when moving across threads. Its only a temporary workaround and you might have faced a similar situation as well, so you might find it 'temporarily useful' to use the BackgroundWorker class resident in System.ComponentModel namespace.

How to use the SmtpMailMan

Using this class is extremely easy, first you'll need to add a reference to the SmtpMailMan.dll file you downloaded above.
The SmtpMailMan class is resident in the SOFTLib namespace, create your SmtpMailMan object, subscribe to the OnMailSent Event and you're ready to go.

The code below shows you how to use the class in simple steps;

C#
...
using SOFTLib.SmtpMailMan;

...

// Declarations come in here
SmtpMailMan smm = new SmtpMailMan();

void InitializeAndUse()
{
    smm.OnMailSent += new SmtpMailMan.MailSentEventHandler( smm_OnMailSent );
    
    // Set up the mail
    smm.To = "mymail@server.com";
    smm.Subject = "My Picture";
    smm.AttachFile("c:\mypic.gif");
    smm.AttachFile("c:\mypic2.gif");
    smm.Body = " Checkout my pix, i'm sure you'll like it";
    
    // Set up client
    smm.Account = "myaccount@yahoo.co.uk";
    smm.SmtpHost = "smtp.mail.yahoo.com";
    smm.Port = 587;
    smm.Ssl = false;
    smm.SendMessage ();
    
    // Thats all there is to it.
}

void smm_OnMailSent(object sender, MailSentEventArgs e)
{
    if(e.Message==null)
    {    
        // Mail was sent successfully
        ...
    }
    else
    {
        // Something went wrong check e.Message for the error message
    }
    
}

Known Issues

There are some know issues (bug - sort of) that arise from the use of the SmtpMailMan, I'll tell you the ones I know and the workaround for it, then I'll update this article as soon as I have found new issues - and if you found them let me know so I can fix them up.

Event Handler Error

<><>(This is more of a design problem form microsoft, everyone that wrote event handlers across event handlers seem to get in the same mess. I may look for alternative later, right now i don't have all the time.) >>

If a mail was not sent successfully and an error message was returned in the Message property of the MailSentEventArgs object e, the handler method gets run twice; first with the original values in the e object, and the second time with the value of e.Message set to null which is equivalent to the Message being sent successfully. The workaround to this is explained in this piece of code;

// create a boolean variable to check if the method has been run already
bool argChecked = false;    // i.e. has the arguments been checked? initialize to false
void smm_OnMailSent(object sender, MailSentEventArgs e)
{
    if(e.Message==null)
    {
        // Mail was sent successfully
        if(!argChecked)
        {
            // Do something, then ...
            ...
            argChecked = true;    // then you set argChecked to true
        }
    }
    else
    {
        // you might just do the same thing as above because
        // you may not want this step repeated. In fact this block will be skipped this time
        ...
    }
}  

When you use the argChecked, you should also have a neat way of setting its value to the original false value. Maybe you could put that after the line that sent your mail.

Okay, that is it for now. You need to let me know the issues you face so I'll be able to do a fix for it until the whole library gets better. I want work improving this library for the next few weeks before I resume school, but you can still send your suggestions and stuffs even later.

Messager

Screenshot - messager.png

Messager is the little dummy (not really dummy) applet that I decided to include into this article as the demo. All it does is demonstrate in the simplest way, the application of the SmptMailMan library. Download it and you may never need to open your mailbox or open Outlook, Thunderbird ... to send just a simple message to anyone. Its very simple, easy to use, and also very easy to understand - if you'd love to read the source code.

Up to you

You're going to need to tell me whatever challenges you faced while using this class. Also send me any bug fixes you made in the class. I really love it when classes are as simple and easy to use as this. This can get better if you help it. I hope you do great things with it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer TEDATA
Nigeria Nigeria
Seun (Laolusrael) loves programming. I learnt 80% of what I know in programming all alone. I use my God-given mind to do a lot of thinking, and...
Currently Seun is a student studying software engineering, and working freelance.

Comments and Discussions

 
GeneralMy vote of 5 Pin
aum5923-Jul-12 12:27
professionalaum5923-Jul-12 12:27 
GeneralMy vote of 5 Pin
xuanchinh9as26-Jul-11 16:33
xuanchinh9as26-Jul-11 16:33 
GeneralPls Help Pin
wasif_Muhammad22-Feb-07 2:23
wasif_Muhammad22-Feb-07 2:23 
GeneralRe: Pls Help Pin
Seun22-Mar-07 4:39
professionalSeun22-Mar-07 4:39 
GeneralGood start...now please finish. Pin
andykernahan20-Feb-07 2:38
andykernahan20-Feb-07 2:38 
GeneralRe: Good start...now please finish. Pin
Seun20-Feb-07 10:40
professionalSeun20-Feb-07 10:40 
GeneralRe: Good start...now please finish. Pin
Seun16-Mar-07 0:08
professionalSeun16-Mar-07 0:08 
GeneralHi Dude Pin
GaryWoodfine 20-Feb-07 2:28
professionalGaryWoodfine 20-Feb-07 2:28 
GeneralRe: Hi Dude Pin
Seun20-Feb-07 10:33
professionalSeun20-Feb-07 10:33 

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.