Not logged in - Login

Sending mail via SMTP

This is an example of how to send an email via SMTP and optionally log into the inbox before connecting to the SMTP server.

public static void SendMail(System.Net.Mail.MailMessage msg)
{
   // do the contract validation here.
   System.Diagnostics.Contracts.Contract.Requires(msg != null, "Parameter 'msg' cannot be null.");
    
   using (System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient())
   {
      // get the mail configuration settings.
      string host = "mail.myserver.com";
      string pop3host = "mail.myserver.com";
      int port = 25;
      string userName = "john@myserver.com";
      string password = "pass@word1";
      bool isSecure = true;
      bool loginToInbox = true;

      // Create an instance of the SMTP object.
      using (System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient())
      {   
         // Set the host and port for the SMTP client
         smtp.Host = host;
         smtp.Port = csWeb.Classes.WebUtility.GetConfigSettingInt("SmtpPort"); //1025;

         // Create an instance of the Network Credentials object.
         System.Net.NetworkCredential cred = new System.Net.NetworkCredential();

         // Set the Username & Password
         cred.UserName = userName;
         cred.Password = password;

         // This value needs to be set to false BEFORE setting the credentials.
         smtp.UseDefaultCredentials = false;
         // Set the credentials for the SMTP object.
         smtp.Credentials = cred;

         // if we are to user a secure connection, set it here
         if (bSecure) smtp.EnableSsl = true;

         // 
         if (bLoginToInbox)
         {
            // get a socket, use our helper class to do most of the work.
            using (Pop3Client pop3 = new Pop3Client(cred.UserName, cred.Password, pop3host))
            {
               // open the inbox.
               pop3.OpenInbox();
               // close the connection
               pop3.CloseConnection();
            }
         }   
         
         // Send the email
         smtp.Send(msg);
      }   
   }
}  

The definition of our helper Pop3 class.

using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using System.Text.RegularExpressions;
using System.Diagnostics;

namespace Pop3
{
   public class Pop3Client : IDisposable
   {
      private Pop3Credential m_credential;

      private const int m_pop3port = 110;
      private const int MAX_BUFFER_READ_SIZE = 256;

      private long m_inboxPosition = 0;
      private long m_directPosition = -1;

      private Socket m_socket = null;

      private Pop3Message m_pop3Message = null;

      public Pop3Credential UserDetails
      {
         set { m_credential = value; }
         get { return m_credential; }
      }

      public string From
      {
         get { return m_pop3Message.From; }
      }

      public string To
      {
         get { return m_pop3Message.To; }
      }

      public string Subject
      {
         get { return m_pop3Message.Subject; }
      }

      public string Body
      {
         get { return m_pop3Message.Body; }
      }

      public IEnumerator MultipartEnumerator
      {
         get { return m_pop3Message.MultipartEnumerator; }
      }

      public bool IsMultipart
      {
         get { return m_pop3Message.IsMultipart; }
      }


      public Pop3Client(string user, string pass, string server)
      {
         this.m_credential = new Pop3Credential(user, pass, server);         
      }

      private Socket GetClientSocket()
      {
         Socket s = null;
         
         try
         {
            IPHostEntry hostEntry = null;

            // Get host related information.
            //hostEntry = Dns.Resolve(m_credential.Server);
            hostEntry = Dns.GetHostEntry(m_credential.Server);

            // Loop through the AddressList to obtain the supported 
            // AddressFamily. This is to avoid an exception that 
            // occurs when the host IP Address is not compatible 
            // with the address family 
            // (typical in the IPv6 case).

            foreach (IPAddress address in hostEntry.AddressList)
            {
               IPEndPoint ipe = new IPEndPoint(address, m_pop3port);

               Socket tempSocket =
                  new Socket(ipe.AddressFamily,
                  SocketType.Stream, ProtocolType.Tcp);

               tempSocket.Connect(ipe);

               if (tempSocket.Connected)
               {
                  // we have a connection.
                  // return this socket ...
                  s = tempSocket;
                  break;
               }
               else
               {
                  // not connected. Dispose of the socket and continue
                  s.Dispose();
                  continue;
               }
            }
         }
         catch (Exception e)
         {
            throw new Exception(e.ToString(), e);
         }

         // throw exception if can't connect ...
         if (s == null)
         {
            throw new Exception("Error : connecting to "
               + m_credential.Server);
         }

         return s;
      }

      //send the data to server
      private void Send(String data)
      {
         if (m_socket == null)
         {
            throw new Exception("Pop3 connection is closed");
         }

         // Convert the string data to byte data 
         // using ASCII encoding.
         byte[] byteData = Encoding.ASCII.GetBytes(data + "\r\n");

         // Begin sending the data to the remote device.
         m_socket.Send(byteData);
      }

      private string GetPop3String()
      {
         if (m_socket == null)
         {
            throw new
               Exception("Connection to POP3 server is closed");
         }

         byte[] buffer = new byte[MAX_BUFFER_READ_SIZE];
         string line = null;

         int byteCount = m_socket.Receive(buffer, buffer.Length, 0);

         line = Encoding.ASCII.GetString(buffer, 0, byteCount);

         return line;
      }

      private void LoginToInbox()
      {
         string returned;

         // send username ...
         Send("user " + m_credential.User);

         // get response ...
         returned = GetPop3String();

         if (!returned.Substring(0, 3).Equals("+OK", StringComparison.CurrentCultureIgnoreCase))
         {
            throw new Exception(string.Format("User login not accepted.\r\nReturn string: '{0}'\r\nUser: '{1}'", returned, this.m_credential.User));
         }

         // send password ...
         Send("pass " + m_credential.Pass);

         // get response ...
         returned = GetPop3String();

         if (!returned.Substring(0, 3).Equals("+OK", StringComparison.CurrentCultureIgnoreCase))
         {
            throw new Exception(string.Format("login/password not accepted.\r\nReturn string: '{0}'\r\nUser: '{1}'\r\nP/W: '{2}'", returned, this.m_credential.User, this.m_credential.Pass));
         }
      }

      public long MessageCount
      {
         get
         {
            long count = 0;

            if (m_socket == null)
            {
               throw new Exception("Pop3 server not connected");
            }

            Send("stat");

            string returned = GetPop3String();

            // if values returned ...
            if (Regex.Match(returned,
               @"^.*\+OK[ |   ]+([0-9]+)[ |   ]+.*$").Success)
            {
               // get number of emails ...
               count = long.Parse(Regex
               .Replace(returned.Replace("\r\n", "")
               , @"^.*\+OK[ |   ]+([0-9]+)[ |   ]+.*$", "$1"));
            }

            return (count);
         }
      }


      public void CloseConnection()
      {
         Send("quit");

         m_socket = null;
         m_pop3Message = null;
      }

      public bool DeleteEmail()
      {
         bool ret = false;

         Send("dele " + m_inboxPosition);

         string returned = GetPop3String();

         if (Regex.Match(returned,
            @"^.*\+OK.*$").Success)
         {
            ret = true;
         }

         return ret;
      }

      public bool NextEmail(long directPosition)
      {
         bool ret;

         if (directPosition >= 0)
         {
            m_directPosition = directPosition;
            ret = NextEmail();
         }
         else
         {
            throw new Exception("Position less than zero");
         }

         return ret;
      }

      public bool NextEmail()
      {
         string returned;

         long pos;

         if (m_directPosition == -1)
         {
            if (m_inboxPosition == 0)
            {
               pos = 1;
            }
            else
            {
               pos = m_inboxPosition + 1;
            }
         }
         else
         {
            pos = m_directPosition + 1;
            m_directPosition = -1;
         }

         // send username ...
         Send("list " + pos.ToString());

         // get response ...
         returned = GetPop3String();

         // if email does not exist at this position
         // then return false ...

         if (returned.Substring(0, 4).Equals("-ERR"))
         {
            return false;
         }

         m_inboxPosition = pos;

         // strip out CRLF ...
         string[] noCr = returned.Split(new char[] { '\r' });

         // get size ...
         string[] elements = noCr[0].Split(new char[] { ' ' });

         long size = long.Parse(elements[2]);

         // ... else read email data
         m_pop3Message = new Pop3Message(m_inboxPosition, size, m_socket);

         return true;
      }

      public void OpenInbox()
      {
         // get a socket ...
         this.m_socket = this.GetClientSocket();         

         // get initial header from POP3 server ...
         string header = GetPop3String();

         if (!header.Substring(0, 3).Equals("+OK"))
         {
            throw new Exception("Invalid initial POP3 response");
         }

         // send login details ...
         LoginToInbox();
      }



      public void Dispose()
      {
         this.Dispose(true);

         // Call SupressFinalize in case a subclass implements a finalizer.
         // Requests that the system not call the finalizer for the specified object.
         GC.SuppressFinalize(this);
      }

      private bool m_bDisposed = false;
      protected virtual void Dispose(bool disposing)
      {
         // If you need thread safety, use a lock around these 
         // operations, as well as in your methods that use the resource.
         do
         {
            // if the object is already disposed, get out now.
            if (this.m_bDisposed) break;

            if (disposing)
            {
               if (this.m_socket != null)
               {
                  this.m_socket.Dispose();
                  this.m_socket = null;
               }
            }

            // Set flag to indicate that the instance has been disposed.
            this.m_bDisposed = true;

         } while (false);
      }
   }
}