More .NET components

SMTP - advanced operations

8-bit MIME #

RFC 6152 introduced 8-bit MIME to make it possible to send MIME messages with parts that use 8bit content transfer encoding, which eliminates the need to encode international text characters.

Rebex SMTP supports sending 8-bit MIME messages through servers that support this extensions. For other servers, Rebex SMTP converts 8-bit MIME parts to use base64 or quoted-printable automatically (if possible).

To disable 8-bit MIME support, use Smtp.EnabledExtensions property. To determine whether the server supports 8-bit MIME, use Smtp.SupportedExtensions property.

Binary MIME #

RFC 3030 introduced binary MIME to make it possible to send MIME messages with parts that use binary content transfer encoding, which makes it possible to send binary attachments without any kind of encoding, reducing the network traffic.

Rebex SMTP supports sending 8-bit MIME messages through servers that support this extensions. For other servers, Rebex SMTP converts 8-bit MIME parts to use base64 or quoted-printable automatically (if possible).

To disable binary MIME support, use Smtp.EnabledExtensions property. To determine whether the server supports binary MIME, use Smtp.SupportedExtensions property.

Pipelining #

RFC 2920 introduced command pipelining to significantly reduce network latency when sending a message to lot of recipients.

Rebex SMTP uses command pipelining by default if available. To disable command pipelining, use Smtp.EnabledExtensions property. To determine if the server supports command pipelining, use Smtp.SupportedExtensions property.

Chunking #

RFC 3030 introduced message data chunking to make sending large emails more efficient and reliable.

Rebex SMTP uses message chunking by default if available. To disable message chunking, use the Smtp.EnabledExtensions property. To determine if the server supports message chunking, use Smtp.SupportedExtensions property.

Specifying SMTP sender #

To submit mail message for delivery to a SMTP server with a specific sender at the SMTP protocol level, use the following overload of Smtp.Send method:

CSharp

// create SMTP client instance, connect, log in
// ...

// send mail as sender@example.org
smtp.Send(mail, "sender@example.org", null);

VisualBasic

' create SMTP client instance, connect, log in
' ...

' send mail as sender@example.org
smtp.Send(mail, "sender@example.org", recipients:=Nothing)

Please note that this only affects the workings of the SMTP protocol such as DSN messages. However, it does not affect the Sender header used to send email on behalf of another user.

Specifying SMTP extensions #

SMTP protocol offers couple of extensions. To determine which extensions are supported by the SMTP server use the Smtp.SupportedExtensions property. By default, all supported extensions are enabled. To disable some extensions use the Smtp.EnabledExtensions property.

CSharp

// create SMTP client instance and connect
// ...

// does the server support binary MIME?
bool binaryMime = (smtp.SupportedExtensions & SmtpExtensions.BinaryMime) == SmtpExtensions.BinaryMime;

// disable command pipelining
smtp.EnabledExtensions &= ~SmtpExtensions.Pipelining;

VisualBasic

' create SMTP client instance and connect
' ...

' does the server support binary MIME?
Dim binaryMime As Boolean = (smtp.SupportedExtensions And SmtpExtensions.BinaryMime) = SmtpExtensions.BinaryMime

' disable command pipelining
smtp.EnabledExtensions = smtp.EnabledExtensions And Not SmtpExtensions.Pipelining

Determining maximum mail size #

To determine maximal size of mail message announced by the SMTP server, use the Smtp.MaxMailSize property.

CSharp

// create SMTP client instance and connect
// ...

// print info about max mail size (0 if not announced)
Console.WriteLine(smtp.MaxMailSize);

VisualBasic

' create SMTP client instance and connect
' ...

' print info about max mail size (0 if not announced)
Console.WriteLine(smtp.MaxMailSize)

Handling rejected recipients #

When the client is submitting an email for delivery, SMTP servers might reject some of the recipients. If this happens, Rebex SMTP cancels the whole operation (by default) and raises the SmtpException exception that contains the list of rejected recipients. This can be detected and handled by custom code:

CSharp

try
{
    smtp.Send(mail);
}
catch (SmtpException ex)
{
    Console.WriteLine("Sending mail failed.");

    // print list of rejected recipients
    SmtpRejectedRecipient[] rejected = ex.GetRejectedRecipients();
    foreach (SmtpRejectedRecipient recipient in rejected)
    {
        Console.WriteLine("Rejected recipient '{0}'.", recipient.Address);
    }
}

VisualBasic

Try
    smtp.Send(mail)
Catch ex As SmtpException
    Console.WriteLine("Sending mail failed.")

    ' print list of rejected recipients
    Dim rejected As SmtpRejectedRecipient() = ex.GetRejectedRecipients()
    For Each recipient As SmtpRejectedRecipient In rejected
        Console.WriteLine("Rejected recipient '{0}'.", recipient.Address)
    Next
End Try

Alternatively, the default behavior can be changed using Smtp object's RejectedRecipient event. This event is raised when a recipient is rejected by the SMTP server during Smtp.Send method call. An event handler receives the server response for each rejected recipient and can make the Smtp object ignore the recipient if desired. This event can also be used to ask the user whether to fail or skip the recipient.

Note: Mail message is only sent when all the recipients have either been accepted by the SMTP server, or their rejection was explicitly ignored by custom event handler code.

Event handler for the RejectedRecipient can look like this:

CSharp

void smtp_RejectedRecipient(object sender, SmtpRejectedRecipientEventArgs e)
{
    // print info about rejected recipient
    Console.WriteLine("Recipient <{0}> rejected by the server ('{1}').", e.Recipient, e.Response.Description);

    // ask user for the answer
    // ...

    if (userAnswer)
    {
        // don't send to this recipient
        e.Ignore = true;
    }
}

VisualBasic

Private Sub smtp_RejectedRecipient(sender As Object, e As SmtpRejectedRecipientEventArgs)
    ' print info about rejected recipient
    Console.WriteLine("Recipient <{0}> rejected by the server ('{1}').", e.Recipient, e.Response.Description)

    ' ask user for the answer
    ' ...

    If userAnswer Then
        ' don't send to this recipient
        e.Ignore = True
    End If
End Sub

Don't forget to register the handler:

CSharp

// register the RejectedRecipient handler
smtp.RejectedRecipient += smtp_RejectedRecipient;

// send mail
smtp.Send(mail);

VisualBasic

' register the RejectedRecipient handler
AddHandler smtp.RejectedRecipient, AddressOf smtp_RejectedRecipient

' send mail
smtp.Send(mail)

Fine-tuning SMTP behavior #

Smtp objects makes it possible to specify various low-level settings and workarounds.