Mail Features

Connection

Ultimate Mail makes it easy for you to establish secure and non-secure connections to your SMTP servers.

Connect and authenticate to an SMTP server

To connect and authenticate to an SMTP server, you can simply perform the following steps

  • Add using directives to your code to create aliases for existing namespaces and avoid having to type the fully qualified type names.
  • Create a new instance of the Smtp class.
  • Now you can connect to the SMTP server with Connect methods.
  • Call the Disconnect method to close the SMTP session when done.
// Create a new instance of the Smtp class.
Smtp client = new Smtp();

// Connect to the server.
client.Connect("myserver");

// Or you can specify the SMTP port with
// client.Connect("myserver", 25);

// Login to the server.
client.Authenticate("user", "password");

// Create a new mail message.
MailMessage msg = new MailMessage();
msg.Subject = "Test Subject";
msg.BodyText = "Content";
msg.From = "from@mydomain.com";
msg.To = "to@somedomain.com";

// And send it.
client.Send(msg);

// Close the connection.
client.Disconnect();
' Create a new instance of the Smtp class.
Dim client As New Smtp()

' Connect to the server.
client.Connect("myserver")

' Or you can specify the SMTP port with
' client.Connect("myserver", 25);

' Login to the server.
client.Authenticate("user", "password")

' Create a new mail message.
Dim msg As New MailMessage()
msg.Subject = "Test Subject"
msg.BodyText = "Content"
msg.From = "from@mydomain.com"
msg.To = "to@somedomain.com"

' And send it.
client.Send(msg)

' Close the connection.
client.Disconnect()
// Create a new instance of the Smtp class.
Smtp client = new Smtp();

// Connect to the server.
client.Connect("myserver", 25, SslSecurityMode.Explicit);

// Login to the server.
client.Authenticate("user", "password");

// Create a new mail message.
MailMessage msg = new MailMessage();
msg.Subject = "Test Subject";
msg.BodyText = "Content";
msg.From = "from@mydomain.com";
msg.To = "to@somedomain.com";

// And send it.
client.Send(msg);

// Close the connection.
client.Disconnect();
' Create a new instance of the Smtp class.
Dim client As New Smtp()

' Connect to the server.
client.Connect("myserver", 25, SslSecurityMode.Explicit)

' Login to the server.
client.Authenticate("user", "password")

' Create a new mail message.
Dim msg As New MailMessage()
msg.Subject = "Test Subject"
msg.BodyText = "Content"
msg.From = "from@mydomain.com"
msg.To = "to@somedomain.com"

' And send it.
client.Send(msg)

' Close the connection.
client.Disconnect()

Explicit and Implicit SSL support

Explicit connection and Implicit connection are two secure methods used to connect to a secure SFTP server. Ultimate SFTP supports both Explicit and Implicit SSL modes.

It also allows you to upgrade an unsecured connection to secure or downgrade a secure connection to unsecure.

Verify server's certificate

By default Sftp validates certificate received from the server automatically. However, you can extend the process for a specific purpose like asking the user whether to accept or reject the server's certificate. You can easily customize the validation process by handling the CertificateReceived event of the Sftp class.

The example following will show you how to do that:

public void HandleCertificateReceivedEvent()
{
    // Create a new instance.
    Smtp client = new Smtp();

    client.CertificateReceived += client_CertificateReceived;

    // Connect to the SMTP server.
    client.Connect("myserver", 25, SslSecurityMode.Explicit);

    // Authenticate.
    client.Authenticate("userName", "password");

    // Do something here...
    // ...
    

    // Disconnect.
    client.Disconnect();
}

/// <summary>
/// Returns all issues of the given certificate.
/// </summary>
/// <param name="status">The certificate verification result.</param>
/// <param name="code">The error code.</param>
/// <returns>Certificate problems.</returns>
private static string GetCertProblem(CertificateVerificationStatus status, int code)
{
    switch (status)
    {
        case CertificateVerificationStatus.TimeNotValid:
            return "Server's certificate has expired or is not valid yet.";

        case CertificateVerificationStatus.Revoked:
            return "Server's certificate has been revoked.";

        case CertificateVerificationStatus.UnknownCa:
            return "Server's certificate was issued by an unknown authority.";

        case CertificateVerificationStatus.UntrustedRoot:
            return "Server's certificate was issued by an untrusted authority.";

        case CertificateVerificationStatus.IncompleteChain:
            return "Server's certificate does not chain up to a trusted root authority.";

        case CertificateVerificationStatus.Malformed:
            return "Server's certificate is malformed.";

        case CertificateVerificationStatus.CnNotMatch:
            return "Server hostname does not match the certificate.";

        case CertificateVerificationStatus.UnknownError:
            return string.Format("Error {0:x} encountered while validating server's certificate.", code);

        default:
            return status.ToString();
    }
}

void client_CertificateReceived(object sender, ComponentPro.Security.CertificateReceivedEventArgs e)
{
    X509Certificate2 cert = e.ServerCertificates[0];

    CertificateVerificationStatus status = e.Status;

    CertificateVerificationStatus[] values = (CertificateVerificationStatus[])Enum.GetValues(typeof(CertificateVerificationStatus));

    StringBuilder sbIssues = new StringBuilder();
    for (int i = 0; i < values.Length; i++)
    {
        // Matches the validation status?
        if ((status & values[i]) == 0)
            continue;

        // The issue is processed.
        status ^= values[i];

        sbIssues.AppendFormat("{0}\r\n", GetCertProblem(values[i], e.ErrorCode));
    }

    Console.WriteLine("Issue: " + sbIssues.ToString());

    Console.WriteLine("Subject: " + cert.SubjectName.Name);
    Console.WriteLine("Issuer: " + cert.IssuerName.Name);
    Console.WriteLine("Effective Date: " + cert.NotBefore);
    Console.WriteLine("Expiry Date: " + cert.NotAfter);
    Console.ResetColor();
    Console.Write("Do you want to accept this certificate (Add to trusted list, Yes, No) [a,y,n]?");

    string response = Console.ReadLine().Trim().ToLower();

    // Add certiticate of the issuer CA to the trusted list.
    if (response == "a")
    {
        e.AddToTrustedRoot = true;
    }
    else if (response == "y")
    {
        e.Accept = true;
    }
}
Public Sub HandleCertificateReceivedEvent()
    ' Create a new instance.
    Dim client As New Smtp()

    AddHandler client.CertificateReceived, AddressOf client_CertificateReceived

    ' Connect to the SMTP server.
    client.Connect("myserver", 25, SslSecurityMode.Explicit)

    ' Authenticate.
    client.Authenticate("userName", "password")

    ' Do something here...
    ' ...


    ' Disconnect.
    client.Disconnect()
End Sub

''' <summary>
''' Returns all issues of the given certificate.
''' </summary>
''' <param name="status">The certificate verification result.</param>
''' <param name="code">The error code.</param>
''' <returns>Certificate problems.</returns>
Private Shared Function GetCertProblem(ByVal status As CertificateVerificationStatus, ByVal code As Integer) As String
    Select Case status
        Case CertificateVerificationStatus.TimeNotValid
            Return "Server's certificate has expired or is not valid yet."

        Case CertificateVerificationStatus.Revoked
            Return "Server's certificate has been revoked."

        Case CertificateVerificationStatus.UnknownCa
            Return "Server's certificate was issued by an unknown authority."

        Case CertificateVerificationStatus.UntrustedRoot
            Return "Server's certificate was issued by an untrusted authority."

        Case CertificateVerificationStatus.IncompleteChain
            Return "Server's certificate does not chain up to a trusted root authority."

        Case CertificateVerificationStatus.Malformed
            Return "Server's certificate is malformed."

        Case CertificateVerificationStatus.CnNotMatch
            Return "Server hostname does not match the certificate."

        Case CertificateVerificationStatus.UnknownError
            Return String.Format("Error {0:x} encountered while validating server's certificate.", code)

        Case Else
            Return status.ToString()
    End Select
End Function

Private Sub client_CertificateReceived(ByVal sender As Object, ByVal e As ComponentPro.Security.CertificateReceivedEventArgs)
    Dim cert As X509Certificate2 = e.ServerCertificates(0)

    Dim status As CertificateVerificationStatus = e.Status

    Dim values() As CertificateVerificationStatus = CType(System.Enum.GetValues(GetType(CertificateVerificationStatus)), CertificateVerificationStatus())

    Dim sbIssues As New StringBuilder()
    For i As Integer = 0 To values.Length - 1
        ' Matches the validation status?
        If (status And values(i)) = 0 Then
            Continue For
        End If

        ' The issue is processed.
        status = status Xor values(i)

        sbIssues.AppendFormat("{0}" & vbCrLf, GetCertProblem(values(i), e.ErrorCode))
    Next i

    Console.WriteLine("Issue: " & sbIssues.ToString())

    Console.WriteLine("Subject: " & cert.SubjectName.Name)
    Console.WriteLine("Issuer: " & cert.IssuerName.Name)
    Console.WriteLine("Effective Date: " & cert.NotBefore)
    Console.WriteLine("Expiry Date: " & cert.NotAfter)
    Console.ResetColor()
    Console.Write("Do you want to accept this certificate (Add to trusted list, Yes, No) [a,y,n]?")

    Dim response As String = Console.ReadLine().Trim().ToLower()

    ' Add certiticate of the issuer CA to the trusted list.
    If response = "a" Then
        e.AddToTrustedRoot = True
    ElseIf response = "y" Then
        e.Accept = True
    End If
End Sub
// Create a new instance.
Smtp client = new Smtp();

// Create a new proxy object.
WebProxyEx proxy = new WebProxyEx();
proxy.Server = "proxyserver"; // Set proxy address here.
proxy.Port = 1080; // Set proxy port here.
proxy.UserName = "username"; // Proxy user name.
proxy.Password = "password"; // Password.

client.Proxy = proxy;

// Connect to the SMTP server.
client.Connect("myserver");

// Authenticate.
client.Authenticate("userName", "password");

// Do something here...
// ...

// Create a new mail message.
MailMessage msg = new MailMessage();
msg.Subject = "Test Subject";
msg.BodyText = "Content";
msg.From = "from@mydomain.com";
msg.To = "to@somedomain.com";

// And send it.
client.Send(msg);

// Disconnect.
client.Disconnect();
' Create a new instance.
Dim client As New Smtp()

' Create a new proxy object.
Dim proxy As New WebProxyEx()
proxy.Server = "proxyserver" ' Set proxy address here.
proxy.Port = 1080 ' Set proxy port here.
proxy.UserName = "username" ' Proxy user name.
proxy.Password = "password" ' Password.

client.Proxy = proxy

' Connect to the SMTP server.
client.Connect("myserver")

' Authenticate.
client.Authenticate("userName", "password")

' Do something here...
' ...

' Create a new mail message.
Dim msg As New MailMessage()
msg.Subject = "Test Subject"
msg.BodyText = "Content"
msg.From = "from@mydomain.com"
msg.To = "to@somedomain.com"

' And send it.
client.Send(msg)

' Disconnect.
client.Disconnect()

Proxy servers

The Smtp class fully supports many proxy servers (often referred to as "proxies"). If you need to connect to your SMTP server through a proxy, simply create a new instance of the WebProxyEx class, set the appropriate properties of the WebProxyEx object, and assign it to the Proxy property of the Smtp class, and the necessary proxy communication will take place.

The Smtp class supports the following Proxy servers:

Proxy Name
SOCKS4 SOCKS4 proxy.
SOCKS4A SOCKS4A proxy (capable of resolving domain names).
SOCKS5 SOCKS5 proxy.
HTTP CONNECT HTTP proxy using CONNECT method.

Authentication

The Smtp class supports many authentication methods including: password, NTLM, and client certificates.

Authenticate with a password

To authenticate a user with password-based authentication, just use this Authenticate method overload. The first parameter is the name of the user, the second one is the user's password.

// Create a new instance of the Smtp class.
Smtp client = new Smtp();

// Connect to the server.
client.Connect("myserver");

// Or you can specify the SMTP port with
// client.Connect("myserver", 25);

// Login to the server.
client.Authenticate("user", "password");

// Create a new mail message.
MailMessage msg = new MailMessage();
msg.Subject = "Test Subject";
msg.BodyText = "Content";
msg.From = "from@mydomain.com";
msg.To = "to@somedomain.com";

// And send it.
client.Send(msg);

// Close the connection.
client.Disconnect();
' Create a new instance of the Smtp class.
Dim client As New Smtp()

' Connect to the server.
client.Connect("myserver")

' Or you can specify the SMTP port with
' client.Connect("myserver", 25);

' Login to the server.
client.Authenticate("user", "password")

' Create a new mail message.
Dim msg As New MailMessage()
msg.Subject = "Test Subject"
msg.BodyText = "Content"
msg.From = "from@mydomain.com"
msg.To = "to@somedomain.com"

' And send it.
client.Send(msg)

' Close the connection.
client.Disconnect()
// Create a new instance of the Smtp class.
Smtp client = new Smtp();

// Connect to the server.
client.Connect("myserver");

// Or you can specify the SMTP port with
// client.Connect("myserver", 25);

// Login to the server using NTLM authentication method.
client.Authenticate("user", "password", SmtpAuthenticationMethod.Ntlm);

// Create a new mail message.
MailMessage msg = new MailMessage();
msg.Subject = "Test Subject";
msg.BodyText = "Content";
msg.From = "from@mydomain.com";
msg.To = "to@somedomain.com";

// And send it.
client.Send(msg);

// Close the connection.
client.Disconnect();
' Create a new instance of the Smtp class.
Dim client As New Smtp()

' Connect to the server.
client.Connect("myserver")

' Or you can specify the SMTP port with
' client.Connect("myserver", 25);

' Login to the server using NTLM authentication method.
client.Authenticate("user", "password", SmtpAuthenticationMethod.Ntlm)

' Create a new mail message.
Dim msg As New MailMessage()
msg.Subject = "Test Subject"
msg.BodyText = "Content"
msg.From = "from@mydomain.com"
msg.To = "to@somedomain.com"

' And send it.
client.Send(msg)

' Close the connection.
client.Disconnect()

Authenticate to an SMTP server using NTLM

To authenticate to an SMTP server using NTLM, specify the enum value SmtpAuthenticationMethod.Ntlm when calling the Authenticate method.

Authenticate with a client certificate

When connecting to a secure SMTP/SSL server, it may ask the client for a certificate to authenticate the user. To provide a certificate for the authentication, handle the CertificateRequired event, and provide the certificate in the event handler. There are several ways doing that:

public void HandleCertificateRequiredEvent()
{
    // Create a new instance.
    Smtp client = new Smtp();

    client.CertificateRequired += client_CertificateRequired;

    // Connect to the SMTP server.
    client.Connect("myserver", 25, SslSecurityMode.Explicit);

    // Authenticate.
    client.Authenticate("userName", "password");

    // Do something here...
    // ...

    // Disconnect.
    client.Disconnect();
}

void client_CertificateRequired(object sender, ComponentPro.Security.CertificateRequiredEventArgs e)
{
    // Load certificates from the local machine.
    X509Store my = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    my.Open(OpenFlags.ReadOnly);

    // Retrieve a list of available certificates.
    X509Certificate2Collection certs = my.Certificates;

    // If no certificate found, return.
    if (certs.Count == 0)
    {
        e.Certificates = null;
        return;
    }

    // Show all certificates.
    Console.WriteLine("Select certificate:");
    for (int i = 0; i <= certs.Count; i++)
    {
        if (i == 0)
        {
            Console.WriteLine(string.Format("{0}. [Nothing, skip this step]", i));
            continue;
        }

        Console.WriteLine(string.Format("{0}. {1}", i, certs[i - 1].SubjectName.Name));
    }

    // And ask user to choose an appropriate certificate.
    while (true)
    {
        Console.Write(string.Format("Select certificate [0 - {0}]: ", certs.Count));

        int certIndex;

        try
        {
            certIndex = int.Parse(Console.ReadLine());
        }
        catch
        {
            Console.WriteLine("ERROR: Wrong certificate index input!");
            continue;
        }

        if (certIndex > 0 && certIndex <= certs.Count)
        {
            e.Certificates = new X509Certificate2Collection(certs[certIndex]);
            return;
        }

        if (certIndex == 0)
            break;

        Console.WriteLine(string.Format("ERROR: You must enter number between 0 and {0}.", certs.Count));
    }
}
Public Sub HandleCertificateRequiredEvent()
    ' Create a new instance.
    Dim client As New Smtp()

    AddHandler client.CertificateRequired, AddressOf client_CertificateRequired

    ' Connect to the SMTP server.
    client.Connect("myserver", 25, SslSecurityMode.Explicit)

    ' Authenticate.
    client.Authenticate("userName", "password")

    ' Do something here...
    ' ...

    ' Disconnect.
    client.Disconnect()
End Sub

Private Sub client_CertificateRequired(ByVal sender As Object, ByVal e As ComponentPro.Security.CertificateRequiredEventArgs)
    ' Load certificates from the local machine.
    Dim my As New X509Store(StoreName.My, StoreLocation.CurrentUser)
    my.Open(OpenFlags.ReadOnly)

    ' Retrieve a list of available certificates.
    Dim certs As X509Certificate2Collection = my.Certificates

    ' If no certificate found, return.
    If certs.Count = 0 Then
        e.Certificates = Nothing
        Return
    End If

    ' Show all certificates.
    Console.WriteLine("Select certificate:")
    For i As Integer = 0 To certs.Count
        If i = 0 Then
            Console.WriteLine(String.Format("{0}. [Nothing, skip this step]", i))
            Continue For
        End If

        Console.WriteLine(String.Format("{0}. {1}", i, certs(i - 1).SubjectName.Name))
    Next i

    ' And ask user to choose an appropriate certificate.
    Do
        Console.Write(String.Format("Select certificate [0 - {0}]: ", certs.Count))

        Dim certIndex As Integer

        Try
            certIndex = Integer.Parse(Console.ReadLine())
        Catch
            Console.WriteLine("ERROR: Wrong certificate index input!")
            Continue Do
        End Try

        If certIndex > 0 AndAlso certIndex <= certs.Count Then
            e.Certificates = New X509Certificate2Collection(certs(certIndex))
            Return
        End If

        If certIndex = 0 Then
            Exit Do
        End If

        Console.WriteLine(String.Format("ERROR: You must enter number between 0 and {0}.", certs.Count))
    Loop
End Sub

Events

You can handle the events in the Smtp class to get notified when an event is triggered.

CertificateRequired event

The CertificateRequired event is triggered when a client certificate is required by the Smtp server, or the one provided was not accepted. For more details, visit topic Authenticate with a client certificate.

public void HandleCertificateRequiredEvent()
{
    // Create a new instance.
    Smtp client = new Smtp();

    client.CertificateRequired += client_CertificateRequired;

    // Connect to the SMTP server.
    client.Connect("myserver", 25, SslSecurityMode.Explicit);

    // Authenticate.
    client.Authenticate("userName", "password");

    // Do something here...
    // ...

    // Disconnect.
    client.Disconnect();
}

void client_CertificateRequired(object sender, ComponentPro.Security.CertificateRequiredEventArgs e)
{
    // Load certificates from the local machine.
    X509Store my = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    my.Open(OpenFlags.ReadOnly);

    // Retrieve a list of available certificates.
    X509Certificate2Collection certs = my.Certificates;

    // If no certificate found, return.
    if (certs.Count == 0)
    {
        e.Certificates = null;
        return;
    }

    // Show all certificates.
    Console.WriteLine("Select certificate:");
    for (int i = 0; i <= certs.Count; i++)
    {
        if (i == 0)
        {
            Console.WriteLine(string.Format("{0}. [Nothing, skip this step]", i));
            continue;
        }

        Console.WriteLine(string.Format("{0}. {1}", i, certs[i - 1].SubjectName.Name));
    }

    // And ask user to choose an appropriate certificate.
    while (true)
    {
        Console.Write(string.Format("Select certificate [0 - {0}]: ", certs.Count));

        int certIndex;

        try
        {
            certIndex = int.Parse(Console.ReadLine());
        }
        catch
        {
            Console.WriteLine("ERROR: Wrong certificate index input!");
            continue;
        }

        if (certIndex > 0 && certIndex <= certs.Count)
        {
            e.Certificates = new X509Certificate2Collection(certs[certIndex]);
            return;
        }

        if (certIndex == 0)
            break;

        Console.WriteLine(string.Format("ERROR: You must enter number between 0 and {0}.", certs.Count));
    }
}
Public Sub HandleCertificateRequiredEvent()
    ' Create a new instance.
    Dim client As New Smtp()

    AddHandler client.CertificateRequired, AddressOf client_CertificateRequired

    ' Connect to the SMTP server.
    client.Connect("myserver", 25, SslSecurityMode.Explicit)

    ' Authenticate.
    client.Authenticate("userName", "password")

    ' Do something here...
    ' ...

    ' Disconnect.
    client.Disconnect()
End Sub

Private Sub client_CertificateRequired(ByVal sender As Object, ByVal e As ComponentPro.Security.CertificateRequiredEventArgs)
    ' Load certificates from the local machine.
    Dim my As New X509Store(StoreName.My, StoreLocation.CurrentUser)
    my.Open(OpenFlags.ReadOnly)

    ' Retrieve a list of available certificates.
    Dim certs As X509Certificate2Collection = my.Certificates

    ' If no certificate found, return.
    If certs.Count = 0 Then
        e.Certificates = Nothing
        Return
    End If

    ' Show all certificates.
    Console.WriteLine("Select certificate:")
    For i As Integer = 0 To certs.Count
        If i = 0 Then
            Console.WriteLine(String.Format("{0}. [Nothing, skip this step]", i))
            Continue For
        End If

        Console.WriteLine(String.Format("{0}. {1}", i, certs(i - 1).SubjectName.Name))
    Next i

    ' And ask user to choose an appropriate certificate.
    Do
        Console.Write(String.Format("Select certificate [0 - {0}]: ", certs.Count))

        Dim certIndex As Integer

        Try
            certIndex = Integer.Parse(Console.ReadLine())
        Catch
            Console.WriteLine("ERROR: Wrong certificate index input!")
            Continue Do
        End Try

        If certIndex > 0 AndAlso certIndex <= certs.Count Then
            e.Certificates = New X509Certificate2Collection(certs(certIndex))
            Return
        End If

        If certIndex = 0 Then
            Exit Do
        End If

        Console.WriteLine(String.Format("ERROR: You must enter number between 0 and {0}.", certs.Count))
    Loop
End Sub
public void HandleCertificateReceivedEvent()
{
    // Create a new instance.
    Smtp client = new Smtp();

    client.CertificateReceived += client_CertificateReceived;

    // Connect to the SMTP server.
    client.Connect("myserver", 25, SslSecurityMode.Explicit);

    // Authenticate.
    client.Authenticate("userName", "password");

    // Do something here...
    // ...
    

    // Disconnect.
    client.Disconnect();
}

/// <summary>
/// Returns all issues of the given certificate.
/// </summary>
/// <param name="status">The certificate verification result.</param>
/// <param name="code">The error code.</param>
/// <returns>Certificate problems.</returns>
private static string GetCertProblem(CertificateVerificationStatus status, int code)
{
    switch (status)
    {
        case CertificateVerificationStatus.TimeNotValid:
            return "Server's certificate has expired or is not valid yet.";

        case CertificateVerificationStatus.Revoked:
            return "Server's certificate has been revoked.";

        case CertificateVerificationStatus.UnknownCa:
            return "Server's certificate was issued by an unknown authority.";

        case CertificateVerificationStatus.UntrustedRoot:
            return "Server's certificate was issued by an untrusted authority.";

        case CertificateVerificationStatus.IncompleteChain:
            return "Server's certificate does not chain up to a trusted root authority.";

        case CertificateVerificationStatus.Malformed:
            return "Server's certificate is malformed.";

        case CertificateVerificationStatus.CnNotMatch:
            return "Server hostname does not match the certificate.";

        case CertificateVerificationStatus.UnknownError:
            return string.Format("Error {0:x} encountered while validating server's certificate.", code);

        default:
            return status.ToString();
    }
}

void client_CertificateReceived(object sender, ComponentPro.Security.CertificateReceivedEventArgs e)
{
    X509Certificate2 cert = e.ServerCertificates[0];

    CertificateVerificationStatus status = e.Status;

    CertificateVerificationStatus[] values = (CertificateVerificationStatus[])Enum.GetValues(typeof(CertificateVerificationStatus));

    StringBuilder sbIssues = new StringBuilder();
    for (int i = 0; i < values.Length; i++)
    {
        // Matches the validation status?
        if ((status & values[i]) == 0)
            continue;

        // The issue is processed.
        status ^= values[i];

        sbIssues.AppendFormat("{0}\r\n", GetCertProblem(values[i], e.ErrorCode));
    }

    Console.WriteLine("Issue: " + sbIssues.ToString());

    Console.WriteLine("Subject: " + cert.SubjectName.Name);
    Console.WriteLine("Issuer: " + cert.IssuerName.Name);
    Console.WriteLine("Effective Date: " + cert.NotBefore);
    Console.WriteLine("Expiry Date: " + cert.NotAfter);
    Console.ResetColor();
    Console.Write("Do you want to accept this certificate (Add to trusted list, Yes, No) [a,y,n]?");

    string response = Console.ReadLine().Trim().ToLower();

    // Add certiticate of the issuer CA to the trusted list.
    if (response == "a")
    {
        e.AddToTrustedRoot = true;
    }
    else if (response == "y")
    {
        e.Accept = true;
    }
}
Public Sub HandleCertificateReceivedEvent()
    ' Create a new instance.
    Dim client As New Smtp()

    AddHandler client.CertificateReceived, AddressOf client_CertificateReceived

    ' Connect to the SMTP server.
    client.Connect("myserver", 25, SslSecurityMode.Explicit)

    ' Authenticate.
    client.Authenticate("userName", "password")

    ' Do something here...
    ' ...


    ' Disconnect.
    client.Disconnect()
End Sub

''' <summary>
''' Returns all issues of the given certificate.
''' </summary>
''' <param name="status">The certificate verification result.</param>
''' <param name="code">The error code.</param>
''' <returns>Certificate problems.</returns>
Private Shared Function GetCertProblem(ByVal status As CertificateVerificationStatus, ByVal code As Integer) As String
    Select Case status
        Case CertificateVerificationStatus.TimeNotValid
            Return "Server's certificate has expired or is not valid yet."

        Case CertificateVerificationStatus.Revoked
            Return "Server's certificate has been revoked."

        Case CertificateVerificationStatus.UnknownCa
            Return "Server's certificate was issued by an unknown authority."

        Case CertificateVerificationStatus.UntrustedRoot
            Return "Server's certificate was issued by an untrusted authority."

        Case CertificateVerificationStatus.IncompleteChain
            Return "Server's certificate does not chain up to a trusted root authority."

        Case CertificateVerificationStatus.Malformed
            Return "Server's certificate is malformed."

        Case CertificateVerificationStatus.CnNotMatch
            Return "Server hostname does not match the certificate."

        Case CertificateVerificationStatus.UnknownError
            Return String.Format("Error {0:x} encountered while validating server's certificate.", code)

        Case Else
            Return status.ToString()
    End Select
End Function

Private Sub client_CertificateReceived(ByVal sender As Object, ByVal e As ComponentPro.Security.CertificateReceivedEventArgs)
    Dim cert As X509Certificate2 = e.ServerCertificates(0)

    Dim status As CertificateVerificationStatus = e.Status

    Dim values() As CertificateVerificationStatus = CType(System.Enum.GetValues(GetType(CertificateVerificationStatus)), CertificateVerificationStatus())

    Dim sbIssues As New StringBuilder()
    For i As Integer = 0 To values.Length - 1
        ' Matches the validation status?
        If (status And values(i)) = 0 Then
            Continue For
        End If

        ' The issue is processed.
        status = status Xor values(i)

        sbIssues.AppendFormat("{0}" & vbCrLf, GetCertProblem(values(i), e.ErrorCode))
    Next i

    Console.WriteLine("Issue: " & sbIssues.ToString())

    Console.WriteLine("Subject: " & cert.SubjectName.Name)
    Console.WriteLine("Issuer: " & cert.IssuerName.Name)
    Console.WriteLine("Effective Date: " & cert.NotBefore)
    Console.WriteLine("Expiry Date: " & cert.NotAfter)
    Console.ResetColor()
    Console.Write("Do you want to accept this certificate (Add to trusted list, Yes, No) [a,y,n]?")

    Dim response As String = Console.ReadLine().Trim().ToLower()

    ' Add certiticate of the issuer CA to the trusted list.
    If response = "a" Then
        e.AddToTrustedRoot = True
    ElseIf response = "y" Then
        e.Accept = True
    End If
End Sub

CertificateReceived event

The CertificateReceived event is triggered when Ultimate Mail's Smtp class has received the server's certificate. For more details, visit topic Verifying server's certificate.

Progress event

Progress event is triggered when a block of data has been sent or received. By handling this event, you can display transfer progress information, source file name, destination file name, etc.

public void ShowProgress()
{
    // Create a new Smtp instance.
    Smtp client = new Smtp();

    // Connect to the SMTP server.
    client.Connect("myserver");

    // Authenticate.
    client.Authenticate("test", "test");

    try
    {
        // Register an event handler.
        client.Progress += client_Progress;

        // Load an existing mail message.
        MailMessage msg = new MailMessage("c:\\temp\\my message.eml");

        // And send it.
        client.Send(msg);
    }
    catch (SmtpException exc)
    {
        Console.WriteLine("Exception: " + exc.Message);
    }

    // Disconnect.
    client.Disconnect();
}

void client_Progress(object sender, SmtpProgressEventArgs e)
{
    // Show progress information.
    if (e.State == SmtpTransferState.Sending)
    {
        Console.Write("\rDownloaded: {0} bytes ({1}% completed)", e.BytesTransferred, e.Percentage);
    }
}
Public Sub ShowProgress()
    ' Create a new Smtp instance.
    Dim client As New Smtp()

    ' Connect to the SMTP server.
    client.Connect("myserver")

    ' Authenticate.
    client.Authenticate("test", "test")

    Try
        ' Register an event handler.
        AddHandler client.Progress, AddressOf client_Progress

        ' Load an existing mail message.
        Dim msg As New MailMessage("c:\temp\my message.eml")

        ' And send it.
        client.Send(msg)
    Catch exc As SmtpException
        Console.WriteLine("Exception: " & exc.Message)
    End Try

    ' Disconnect.
    client.Disconnect()
End Sub

Private Sub client_Progress(ByVal sender As Object, ByVal e As SmtpProgressEventArgs)
    ' Show progress information.
    If e.State = SmtpTransferState.Sending Then
        Console.Write(vbCr & "Downloaded: {0} bytes ({1}% completed)", e.BytesTransferred, e.Percentage)
    End If
End Sub
public void HandleCommandSentResponseReadEvents()
{
    // Create a new instance.
    Smtp client = new Smtp();

    // Register event handlers.
    client.CommandResponse += client_CommandResponse;

    // Connect to the SMTP server.
    client.Connect("server");

    // Authenticate.
    client.Authenticate("test", "test");

    // ...

    // Do something here
    // ...

    // Create a new mail message.
    MailMessage msg = new MailMessage();
    msg.Subject = "Test Subject";
    msg.BodyText = "Content";
    msg.From = "from@mydomain.com";
    msg.To = "to@somedomain.com";

    // And send it.
    client.Send(msg);

    // ...

    // Disconnect.
    client.Disconnect();
}

void client_CommandResponse(object sender, CommandResponseEventArgs e)
{
    if (e.Command != null)
        Console.WriteLine("CMD>       " + e.Command);
    else
        Console.WriteLine("RESPONSE>  " + e.Response);
}
Public Sub HandleCommandSentResponseReadEvents()
    ' Create a new instance.
    Dim client As New Smtp()

    ' Register event handlers.
    AddHandler client.CommandResponse, AddressOf client_CommandResponse

    ' Connect to the SMTP server.
    client.Connect("server")

    ' Authenticate.
    client.Authenticate("test", "test")

    ' ...

    ' Do something here
    ' ...

    ' Create a new mail message.
    Dim msg As New MailMessage()
    msg.Subject = "Test Subject"
    msg.BodyText = "Content"
    msg.From = "from@mydomain.com"
    msg.To = "to@somedomain.com"

    ' And send it.
    client.Send(msg)

    ' ...

    ' Disconnect.
    client.Disconnect()
End Sub

Private Sub client_CommandResponse(ByVal sender As Object, ByVal e As CommandResponseEventArgs)
    If e.Command IsNot Nothing Then
        Console.WriteLine("CMD>       " & e.Command)
    Else
        Console.WriteLine("RESPONSE>  " & e.Response)
    End If
End Sub

CommandResponse event

The CommandResponse event is triggered when a command has been sent to the SMTP server or when Mail component has received a response from the server. This event is commonly used to add trace log capabilities to your applications. For more details on how to handle this event, visit Making a trace log using events. There is still another convenient way to add log capabilities to your application is using the XTrace class.

StateChanged event

The StateChanged event is triggered when the state of the Smtp object has been changed. By handling this event, you will get notification when a connection has been established or the connection has been lost.

public void HandleStateChangedEvent()
{
    // Create a new instance.
    Smtp client = new Smtp();

    client.StateChanged += client_StateChanged;

    // Connect to the SMTP server.
    client.Connect("server");

    // Authenticate.
    client.Authenticate("test", "test");

    // ...

    // Do something here

    // ...

    // Disconnect.
    client.Disconnect();
}

void client_StateChanged(object sender, SmtpStateChangedEventArgs e)
{
    Console.WriteLine("State changed, old state: {0}, new state: {1}", e.OldState, e.OldState);
}
Public Sub HandleStateChangedEvent()
    ' Create a new instance.
    Dim client As New Smtp()

    AddHandler client.StateChanged, AddressOf client_StateChanged

    ' Connect to the SMTP server.
    client.Connect("server")

    ' Authenticate.
    client.Authenticate("test", "test")

    ' ...

    ' Do something here

    ' ...

    ' Disconnect.
    client.Disconnect()
End Sub

Private Sub client_StateChanged(ByVal sender As Object, ByVal e As SmtpStateChangedEventArgs)
    Console.WriteLine("State changed, old state: {0}, new state: {1}", e.OldState, e.OldState)
End Sub

Send messages

The Smtp class also has the comprehensive API to manage mail messages.

Send a simple message

Mail can be sent using Smtp with only a few lines of code. In fact, for the simplest method of sending, no knowledge of message format is required at all.

The following steps will help you to do that:

// Create a new instance of the Smtp class.
Smtp client = new Smtp();

// Connect to the server.
client.Connect("myserver");

// Or you can specify the SMTP port with
// client.Connect("myserver", 25);

// Login to the server.
client.Authenticate("user", "password");

// Create a new mail message.
MailMessage msg = new MailMessage();
msg.Subject = "Test Subject";
msg.BodyText = "Content";
msg.From = "from@mydomain.com";
msg.To = "to@somedomain.com";

// And send it.
client.Send(msg);

// Close the connection.
client.Disconnect();
' Create a new instance of the Smtp class.
Dim client As New Smtp()

' Connect to the server.
client.Connect("myserver")

' Or you can specify the SMTP port with
' client.Connect("myserver", 25);

' Login to the server.
client.Authenticate("user", "password")

' Create a new mail message.
Dim msg As New MailMessage()
msg.Subject = "Test Subject"
msg.BodyText = "Content"
msg.From = "from@mydomain.com"
msg.To = "to@somedomain.com"

' And send it.
client.Send(msg)

' Close the connection.
client.Disconnect()
const string serverName = "myserver";
const string user = "name@domain.com";
const string password = "mytestpassword";
const int port = 465;
const SslSecurityMode securityMode = SslSecurityMode.Implicit;

Smtp client = new Smtp();
try
{
    MailMessage mmMessage = new MailMessage();
    mmMessage.From.Add("from@thedomain.com");
    mmMessage.To.Add("name@domain.com");
    mmMessage.To.Add("someone@domain.com");
    mmMessage.CC.Add("someone2@domain.com");
    mmMessage.Bcc.Add("someone3@domain.com");
    mmMessage.Subject = "Test Subject";
    mmMessage.BodyText = "Test Content";

    Console.WriteLine("Connecting SMTP server: {0}:{1}...", serverName, port);
    // Connect to the server.
    client.Connect(serverName, port, securityMode);

    // Login to the server.
    Console.WriteLine("Logging in as {0}...", user);
    client.Authenticate(user, password);

    Console.WriteLine("Sending mail message...");
    client.Send(mmMessage);
    Console.WriteLine("Message sent...");

    // Disconnect.
    Console.WriteLine("Disconnecting...");
    client.Disconnect();
}
catch (SmtpException smtpExc)
{
    MessageBox.Show(string.Format("An SMTP error occurred: {0}, ErrorStatus: {1}", smtpExc.Message, smtpExc.Status));
}
catch (Exception exc)
{
    MessageBox.Show(string.Format("An error occurred: {0}", exc.Message));
}
Const serverName As String = "myserver"
Const user As String = "name@domain.com"
Const password As String = "mytestpassword"
Const port As Integer = 465
Const securityMode As SslSecurityMode = SslSecurityMode.Implicit

Dim client As New Smtp()
Try
    Dim mmMessage As New MailMessage()
    mmMessage.From.Add("from@thedomain.com")
    mmMessage.To.Add("name@domain.com")
    mmMessage.To.Add("someone@domain.com")
    mmMessage.CC.Add("someone2@domain.com")
    mmMessage.Bcc.Add("someone3@domain.com")
    mmMessage.Subject = "Test Subject"
    mmMessage.BodyText = "Test Content"

    Console.WriteLine("Connecting SMTP server: {0}:{1}...", serverName, port)
    ' Connect to the server.
    client.Connect(serverName, port, securityMode)

    ' Login to the server.
    Console.WriteLine("Logging in as {0}...", user)
    client.Authenticate(user, password)

    Console.WriteLine("Sending mail message...")
    client.Send(mmMessage)
    Console.WriteLine("Message sent...")

    ' Disconnect.
    Console.WriteLine("Disconnecting...")
    client.Disconnect()
Catch smtpExc As SmtpException
    MessageBox.Show(String.Format("An SMTP error occurred: {0}, ErrorStatus: {1}", smtpExc.Message, smtpExc.Status))
Catch exc As Exception
    MessageBox.Show(String.Format("An error occurred: {0}", exc.Message))
End Try

Send mail message to multiple recipients

You may have to send an email message to multiple recipients. UltimateMail makes sending to multiple recipients easy to manage, by representing these types as collections of the MailMessage object.

The example below illustrates how to send a mail message to multiple recipients:

Send multiple messages

It's better and faster to send multiple messages in one connection than sending them in separate connections. The following example shows how to accomplish this:

const string serverName = "myserver";
const string user = "name@domain.com";
const string password = "mytestpassword";
const int port = 465;
const SslSecurityMode securityMode = SslSecurityMode.Implicit;

Smtp client = new Smtp();
try
{
    MailMessage mmMessage = new MailMessage();
    mmMessage.From.Add("from@thedomain.com");
    mmMessage.To.Add("name@domain.com");
    mmMessage.Subject = "Test Subject";
    mmMessage.BodyText = "Test Content";

    MailMessage mmMessage2 = new MailMessage();
    mmMessage.From.Add("from@thedomain.com");
    mmMessage.To.Add("someone@thedomain.com");
    mmMessage.Subject = "Test Subject";
    mmMessage.BodyText = "Test Content";

    Console.WriteLine("Connecting SMTP server: {0}:{1}...", serverName, port);
    // Connect to the server.
    client.Connect(serverName, port, securityMode);

    // Login to the server.
    Console.WriteLine("Logging in as {0}...", user);
    client.Authenticate(user, password);

    Console.WriteLine("Sending the first message...");
    client.Send(mmMessage);
    Console.WriteLine("Message sent...");

    Console.WriteLine("Sending the second message...");
    client.Send(mmMessage2);
    Console.WriteLine("Message sent...");

    // Disconnect.
    Console.WriteLine("Disconnecting...");
    client.Disconnect();
}
catch (SmtpException smtpExc)
{
    MessageBox.Show(string.Format("An SMTP error occurred: {0}, ErrorStatus: {1}", smtpExc.Message, smtpExc.Status));
}
catch (Exception exc)
{
    MessageBox.Show(string.Format("An error occurred: {0}", exc.Message));
}
Const serverName As String = "myserver"
Const user As String = "name@domain.com"
Const password As String = "mytestpassword"
Const port As Integer = 465
Const securityMode As SslSecurityMode = SslSecurityMode.Implicit

Dim client As New Smtp()
Try
    Dim mmMessage As New MailMessage()
    mmMessage.From.Add("from@thedomain.com")
    mmMessage.To.Add("name@domain.com")
    mmMessage.Subject = "Test Subject"
    mmMessage.BodyText = "Test Content"

    Dim mmMessage2 As New MailMessage()
    mmMessage.From.Add("from@thedomain.com")
    mmMessage.To.Add("someone@thedomain.com")
    mmMessage.Subject = "Test Subject"
    mmMessage.BodyText = "Test Content"

    Console.WriteLine("Connecting SMTP server: {0}:{1}...", serverName, port)
    ' Connect to the server.
    client.Connect(serverName, port, securityMode)

    ' Login to the server.
    Console.WriteLine("Logging in as {0}...", user)
    client.Authenticate(user, password)

    Console.WriteLine("Sending the first message...")
    client.Send(mmMessage)
    Console.WriteLine("Message sent...")

    Console.WriteLine("Sending the second message...")
    client.Send(mmMessage2)
    Console.WriteLine("Message sent...")

    ' Disconnect.
    Console.WriteLine("Disconnecting...")
    client.Disconnect()
Catch smtpExc As SmtpException
    MessageBox.Show(String.Format("An SMTP error occurred: {0}, ErrorStatus: {1}", smtpExc.Message, smtpExc.Status))
Catch exc As Exception
    MessageBox.Show(String.Format("An error occurred: {0}", exc.Message))
End Try
const string serverName = "myserver";
const string user = "name@domain.com";
const string password = "mytestpassword";
const int port = 465;
const SslSecurityMode securityMode = SslSecurityMode.Implicit;

Smtp client = new Smtp();
try
{
    MailMessage mmMessage = new MailMessage();
    mmMessage.From.Add("from@thedomain.com");
    mmMessage.To.Add("name@domain.com");
    mmMessage.Subject = "Test Subject";
    mmMessage.BodyText = "Test Content";
    // Attach file to the message.
    mmMessage.Attachments.Add("myfile.dat");

    // Attach content data from a stream to the message.
    Stream stream = new FileStream("myfile.dat", FileMode.Open);
    // The stream will be automatically closed after adding to the attachment list.
    mmMessage.Attachments.Add(new Attachment(stream, "teststream"));

    Console.WriteLine("Connecting SMTP server: {0}:{1}...", serverName, port);
    // Connect to the server.
    client.Connect(serverName, port, securityMode);

    // Login to the server.
    Console.WriteLine("Logging in as {0}...", user);
    client.Authenticate(user, password);

    Console.WriteLine("Sending the message with attachment...");
    client.Send(mmMessage);
    Console.WriteLine("Message sent...");

    // Disconnect.
    Console.WriteLine("Disconnecting...");
    client.Disconnect();
}
catch (SmtpException smtpExc)
{
    MessageBox.Show(string.Format("An SMTP error occurred: {0}, ErrorStatus: {1}", smtpExc.Message, smtpExc.Status));
}
catch (Exception exc)
{
    MessageBox.Show(string.Format("An error occurred: {0}", exc.Message));
}
Const serverName As String = "myserver"
Const user As String = "name@domain.com"
Const password As String = "mytestpassword"
Const port As Integer = 465
Const securityMode As SslSecurityMode = SslSecurityMode.Implicit

Dim client As New Smtp()
Try
    Dim mmMessage As New MailMessage()
    mmMessage.From.Add("from@thedomain.com")
    mmMessage.To.Add("name@domain.com")
    mmMessage.Subject = "Test Subject"
    mmMessage.BodyText = "Test Content"
    ' Attach file to the message.
    mmMessage.Attachments.Add("myfile.dat")

    ' Attach content data from a stream to the message.
    Dim stream As Stream = New FileStream("myfile.dat", FileMode.Open)
    ' The stream will be automatically closed after adding to the attachment list.
    mmMessage.Attachments.Add(New Attachment(stream, "teststream"))

    Console.WriteLine("Connecting SMTP server: {0}:{1}...", serverName, port)
    ' Connect to the server.
    client.Connect(serverName, port, securityMode)

    ' Login to the server.
    Console.WriteLine("Logging in as {0}...", user)
    client.Authenticate(user, password)

    Console.WriteLine("Sending the message with attachment...")
    client.Send(mmMessage)
    Console.WriteLine("Message sent...")

    ' Disconnect.
    Console.WriteLine("Disconnecting...")
    client.Disconnect()
Catch smtpExc As SmtpException
    MessageBox.Show(String.Format("An SMTP error occurred: {0}, ErrorStatus: {1}", smtpExc.Message, smtpExc.Status))
Catch exc As Exception
    MessageBox.Show(String.Format("An error occurred: {0}", exc.Message))
End Try

Send mail with attachments

MIME attachments are represented by Attachment objects, and are managed by use of the MailMessage.Attachments property. The source of attachments can be a file, a MemoryStream, or any other type of .NET Framework Stream. As a result, the ways an attachment can be created is limitless. This topic demonstrates two ways of creating an attachment.

Send mail with embedded resources (images{cm

sound...), CodeFilePath: Mail/CS/MHTMail.cs} The code snippet below shows you how to create an e-mail message and add an image from local disk as a LinkedResource object and send the message:

const string serverName = "myserver";
const string user = "name@domain.com";
const string password = "mytestpassword";
const int port = 465;
const SslSecurityMode securityMode = SslSecurityMode.Implicit;

Smtp client = new Smtp();
try
{
    MailMessage msg = new MailMessage();
    msg.Load("mycontent.html");
    msg.From.Add("from@thedomain.com");
    msg.To.Add("name@domain.com");
    msg.Subject = "Test Subject";                

    Console.WriteLine("Connecting SMTP server: {0}:{1}...", serverName, port);
    // Connect to the server.
    client.Connect(serverName, port, securityMode);

    // Login to the server.
    Console.WriteLine("Logging in as {0}...", user);
    client.Authenticate(user, password);

    Console.WriteLine("Sending message...");
    client.Send(msg);
    Console.WriteLine("Message sent...");

    // Disconnect.
    Console.WriteLine("Disconnecting...");
    client.Disconnect();
}
catch (SmtpException smtpExc)
{
    MessageBox.Show(string.Format("An SMTP error occurred: {0}, ErrorStatus: {1}", smtpExc.Message, smtpExc.Status));
}
catch (Exception exc)
{
    MessageBox.Show(string.Format("An error occurred: {0}", exc.Message));
}
Const serverName As String = "myserver"
Const user As String = "name@domain.com"
Const password As String = "mytestpassword"
Const port As Integer = 465
Const securityMode As SslSecurityMode = SslSecurityMode.Implicit

Dim client As New Smtp()
Try
    Dim msg As New MailMessage()
    msg.Load("mycontent.html")
    msg.From.Add("from@thedomain.com")
    msg.To.Add("name@domain.com")
    msg.Subject = "Test Subject"

    Console.WriteLine("Connecting SMTP server: {0}:{1}...", serverName, port)
    ' Connect to the server.
    client.Connect(serverName, port, securityMode)

    ' Login to the server.
    Console.WriteLine("Logging in as {0}...", user)
    client.Authenticate(user, password)

    Console.WriteLine("Sending message...")
    client.Send(msg)
    Console.WriteLine("Message sent...")

    ' Disconnect.
    Console.WriteLine("Disconnecting...")
    client.Disconnect()
Catch smtpExc As SmtpException
    MessageBox.Show(String.Format("An SMTP error occurred: {0}, ErrorStatus: {1}", smtpExc.Message, smtpExc.Status))
Catch exc As Exception
    MessageBox.Show(String.Format("An error occurred: {0}", exc.Message))
End Try

Send HTML mail

UltimateMail makes it easy to create a complete HTML email message with only a few lines of code. To accomplish this, tou can either set the property BodyHtml or call the Load method of the MailMessage class.

The following example illustrates how to load a HTML file from disk as the body of a mail message and send it:

Send mail directly without SMTP server

In some scenarios, your SMTP server is either not available or you want to directly send a message to the specified addresses. In this case, you can use the SendDirect method to directly send the message. The target SMTP server address is determined by asking the DNS system for MX records of the target domain, all are done by the UltimateMail component and you don't have to care about it. But firstly, you have to make sure that the SMTP port 25 is allowed for the direct connections to the remote SMTP servers, and the DNS subsystem must be working. See the following example for more details:

try
{
    MailMessage msg = new MailMessage();
    msg.From.Add("from@thedomain.com");
    msg.To.Add("name@domain.com");
    msg.Subject = "Test Subject";
    msg.BodyText = "Test Content";

    Console.WriteLine("Sending a message directly...");
    Smtp.SendDirect(msg);
    Console.WriteLine("Message sent...");
}
catch (SmtpException smtpExc)
{
    MessageBox.Show(string.Format("An SMTP error occurred: {0}, ErrorStatus: {1}", smtpExc.Message, smtpExc.Status));
}
catch (Exception exc)
{
    MessageBox.Show(string.Format("An error occurred: {0}", exc.Message));
}
Try
    Dim msg As New MailMessage()
    msg.From.Add("from@thedomain.com")
    msg.To.Add("name@domain.com")
    msg.Subject = "Test Subject"
    msg.BodyText = "Test Content"

    Console.WriteLine("Sending a message directly...")
    Smtp.SendDirect(msg)
    Console.WriteLine("Message sent...")
Catch smtpExc As SmtpException
    MessageBox.Show(String.Format("An SMTP error occurred: {0}, ErrorStatus: {1}", smtpExc.Message, smtpExc.Status))
Catch exc As Exception
    MessageBox.Show(String.Format("An error occurred: {0}", exc.Message))
End Try
try
{
    MailMessage msg = new MailMessage();
    msg.From.Add("from@thedomain.com");
    msg.To.Add("name@domain.com");
    msg.Subject = "Test Subject";
    msg.BodyText = "Test Content";

    Console.WriteLine("Sending a message directly...");
    Smtp.SendDirect(msg);
    Console.WriteLine("Message sent...");
}
catch (SmtpException smtpExc)
{
    MessageBox.Show(string.Format("An SMTP error occurred: {0}, ErrorStatus: {1}", smtpExc.Message, smtpExc.Status));
}
catch (Exception exc)
{
    MessageBox.Show(string.Format("An error occurred: {0}", exc.Message));
}
Try
    Dim msg As New MailMessage()
    msg.From.Add("from@thedomain.com")
    msg.To.Add("name@domain.com")
    msg.Subject = "Test Subject"
    msg.BodyText = "Test Content"

    Console.WriteLine("Sending a message directly...")
    Smtp.SendDirect(msg)
    Console.WriteLine("Message sent...")
Catch smtpExc As SmtpException
    MessageBox.Show(String.Format("An SMTP error occurred: {0}, ErrorStatus: {1}", smtpExc.Message, smtpExc.Status))
Catch exc As Exception
    MessageBox.Show(String.Format("An error occurred: {0}", exc.Message))
End Try

Send mail with Delivery Status Notification (DSN)

Delivery status notification (DSN) is an extension added to SMTP to extend the types of and situations when the sender will be notified of the status of a send message. The DSN is represented by the enumerate DeliveryStatusNotificationType and accessible via the DeliveryStatusNotificationType property of the Smtp class.

The example below demonstrates how to use DSN:

Sending mail through IIS

It is very easy to send a mail message through IIS spool folder with UltimateMail component. All you need to do is calling the static Send methods that have the SmtpSendOptions parameter and set the property UseIisPickupDirectory to true. The following example illustrates how to do that.

MailMessage msg = new MailMessage();
msg.From.Add("from@thedomain.com");
msg.To.Add("name@domain.com");
msg.Subject = "Test Subject";
msg.BodyText = "Test Content";

Console.WriteLine("Sending a message through IIS spool folder...");
SmtpSendOptions options = new SmtpSendOptions();
options.UseIisPickupDirectory = true;
Smtp.Send(msg, options);
Console.WriteLine("Message sent...");
Dim msg As New MailMessage()
msg.From.Add("from@thedomain.com")
msg.To.Add("name@domain.com")
msg.Subject = "Test Subject"
msg.BodyText = "Test Content"

Console.WriteLine("Sending a message through IIS spool folder...")
Dim options As New SmtpSendOptions()
options.UseIisPickupDirectory = True
Smtp.Send(msg, options)
Console.WriteLine("Message sent...")

Advanced SMTP features

The library also comes with some advanced features below:

Use asynchronous methods

Smtp provides a number of methods allowing you to asynchronously connect, login, send, etc. Their names always end with Async. This means the method will begin some operation on a new thread and immediately return to the caller. When the operation has completed, the corresponding event will be raised notifying you that the operation has completed and in the event handler method you can check for the error and use the result, if provided.

The example following demonstrates how to connect to an SMTP server and send a messages asynchronously:

            // Create a new instance of the Smtp class.
            Smtp client = new Smtp();

            // Connect to the server.
            client.Connect("myserver");

            // Or you can specify the SMTP port with
            // client.Connect("myserver", 25);

            // Login to the server.
            client.Authenticate("user", "password");

            // ...

            // Create a new mail message.
            MailMessage msg = new MailMessage();
            msg.Subject = "Test Subject";
            msg.BodyText = "Content";
            msg.From = "from@mydomain.com";
            msg.To = "to@somedomain.com";

            // Send the message.
            await client.SendAsync(msg);

            // ...

            Console.WriteLine("Message sent successfully.");

            // Disconnect.
            client.Disconnect();
            ' Create a new instance of the Smtp class.
            Dim client As New Smtp()

            ' Connect to the server.
            client.Connect("myserver")

            ' Or you can specify the SMTP port with
            ' client.Connect("myserver", 25);

            ' Login to the server.
            client.Authenticate("user", "password")

            ' ...

            ' Create a new mail message.
            Dim msg As New MailMessage()
            msg.Subject = "Test Subject"
            msg.BodyText = "Content"
            msg.From = "from@mydomain.com"
            msg.To = "to@somedomain.com"

            ' Send the message.
            Await client.SendAsync(msg)

            ' ...

            Console.WriteLine("Message sent successfully.")

            ' Disconnect.
            client.Disconnect()
// SMTP server information.
const string serverName = "myserver";
const string user = "name@domain.com";
const string password = "mytestpassword";
const int port = 465;
const SslSecurityMode securityMode = SslSecurityMode.Implicit;

// Create a new instance of the Smtp class.
Smtp client = new Smtp();

// Connect to the server.
client.Connect(serverName, port, securityMode);

// Login to the server.
client.Authenticate(user, password);

// Send a command.
client.SendCommand("HELP");

// Read response from the server.
SmtpResponse response = client.ReadResponse();

// Print out the response.
Console.WriteLine(response.RawResponse);

// Close the connection.
client.Disconnect();
' SMTP server information.
Const serverName As String = "myserver"
Const user As String = "name@domain.com"
Const password As String = "mytestpassword"
Const port As Integer = 465
Const securityMode As SslSecurityMode = SslSecurityMode.Implicit

' Create a new instance of the Smtp class.
Dim client As New Smtp()

' Connect to the server.
client.Connect(serverName, port, securityMode)

' Login to the server.
client.Authenticate(user, password)

' Send a command.
client.SendCommand("HELP")

' Read response from the server.
Dim response As SmtpResponse = client.ReadResponse()

' Print out the response.
Console.WriteLine(response.RawResponse)

' Close the connection.
client.Disconnect()

Send custom commands

Explicitly sending commands to an SMTP server is usually not necessary. Almost all commands that could conceivably be sent to an SMTP server are encapsulated by high-level methods. However, to send a command to an SMTP server, simply call the SendCommand method, and to get the response from the SMTP server, call the ReadResponse method.

The example below sends the "HELP" command to an SMTP server and prints out the response:

Obtain mailbox information

The simplest way to obtain information about a specified mailbox is using GetMailboxStat method. The method returns a SmtpMailboxStat object containing information about the mailbox you have requested.

Unable to read code file 'C:\ComponentPro\Website2.0\Sites\ComponentPro\CodeExamples\Mail\CS\Smtp\GetMailboxInfo.cs'.
Unable to read code file 'C:\ComponentPro\Website2.0\Sites\ComponentPro\CodeExamples\Mail\VB\Smtp\GetMailboxInfo.vb'.
public void DoAbort()
{
    // Create a new Smtp instance.
    Smtp client = new Smtp();

    // Connect to the SMTP server.
    client.Connect("myserver");

    // Authenticate.
    client.Authenticate("test", "test");

    try
    {
        // Register an event handler.
        client.Progress += client_Progress;

        // Load an existing mail message.
        MailMessage msg = new MailMessage("c:\\temp\\my message.eml");

        // And send it.
        client.Send(msg);
    }
    catch (SmtpException exc)
    {
        Console.WriteLine("Exception: " + exc.Message);
    }

    // Disconnect.
    client.Disconnect();
}

void client_Progress(object sender, SmtpProgressEventArgs e)
{
    // Abort the download operation if the bytes transferred is greater than or equal to 500Kb.
    if (e.State == SmtpTransferState.Sending && e.BytesTransferred >= 1024 * 500)
    {
        ((Smtp)sender).Cancel();
    }
}
Public Sub DoAbort()
    ' Create a new Smtp instance.
    Dim client As New Smtp()

    ' Connect to the SMTP server.
    client.Connect("myserver")

    ' Authenticate.
    client.Authenticate("test", "test")

    Try
        ' Register an event handler.
        AddHandler client.Progress, AddressOf client_Progress

        ' Load an existing mail message.
        Dim msg As New MailMessage("c:\temp\my message.eml")

        ' And send it.
        client.Send(msg)
    Catch exc As SmtpException
        Console.WriteLine("Exception: " & exc.Message)
    End Try

    ' Disconnect.
    client.Disconnect()
End Sub

Private Sub client_Progress(ByVal sender As Object, ByVal e As SmtpProgressEventArgs)
    ' Abort the download operation if the bytes transferred is greater than or equal to 500Kb.
    If e.State = SmtpTransferState.Sending AndAlso e.BytesTransferred >= 1024 * 500 Then
        CType(sender, Smtp).Cancel()
    End If
End Sub

Cancel an operation

To abort any transfer (downloading or uploading message) in progress you can either call the Cancel method or simply close the connection by calling the Disconnect or DisconnectAsync method.

Display progress while transferring data

When the mail message to transfer is big and your application may take time to transfer, you may wish to show the progress of the transfer to the user. The Smtp class provides progress notification through the Progress event. The Progress event is raised periodically while data transfer is in progress, making accessible necessary data to display progress information, such as the size of the file and the number of transferred bytes.

The following steps show you how to use the Progress event to show progress information while transferring a file:

public void ShowProgress()
{
    // Create a new Smtp instance.
    Smtp client = new Smtp();

    // Connect to the SMTP server.
    client.Connect("myserver");

    // Authenticate.
    client.Authenticate("test", "test");

    try
    {
        // Register an event handler.
        client.Progress += client_Progress;

        // Load an existing mail message.
        MailMessage msg = new MailMessage("c:\\temp\\my message.eml");

        // And send it.
        client.Send(msg);
    }
    catch (SmtpException exc)
    {
        Console.WriteLine("Exception: " + exc.Message);
    }

    // Disconnect.
    client.Disconnect();
}

void client_Progress(object sender, SmtpProgressEventArgs e)
{
    // Show progress information.
    if (e.State == SmtpTransferState.Sending)
    {
        Console.Write("\rDownloaded: {0} bytes ({1}% completed)", e.BytesTransferred, e.Percentage);
    }
}
Public Sub ShowProgress()
    ' Create a new Smtp instance.
    Dim client As New Smtp()

    ' Connect to the SMTP server.
    client.Connect("myserver")

    ' Authenticate.
    client.Authenticate("test", "test")

    Try
        ' Register an event handler.
        AddHandler client.Progress, AddressOf client_Progress

        ' Load an existing mail message.
        Dim msg As New MailMessage("c:\temp\my message.eml")

        ' And send it.
        client.Send(msg)
    Catch exc As SmtpException
        Console.WriteLine("Exception: " & exc.Message)
    End Try

    ' Disconnect.
    client.Disconnect()
End Sub

Private Sub client_Progress(ByVal sender As Object, ByVal e As SmtpProgressEventArgs)
    ' Show progress information.
    If e.State = SmtpTransferState.Sending Then
        Console.Write(vbCr & "Downloaded: {0} bytes ({1}% completed)", e.BytesTransferred, e.Percentage)
    End If
End Sub