The remote certificate is invalid according to the validation procedure

If you get “The remote certificate is invalid according to the validation procedure” exception while trying to establish SSL/TLS connection using Mail.dll SMTP, POP3 and IMAP .NET component, most likely your server certificate is self-signed or you are using incorrect host name to connect.

Incorrect host name

Host name must match the name on certificate: for example imap.example.com and example.com may point to the same server, but if the certificate is issued to imap.example.com only, this is the only address you should use.

Double check if the name you pass to Connect or ConnectSSL method is correct and matches the certificate.

Self-signed certificates

You can accept self-signed certificates using Mail.dll SMTP, POP3 and IMAP .net clients.

First you need to subscribe to ServerCertificateValidate event, so you can manually verify the certificate presented by the server.

Then you should create a Validate method, that validates the certificate (ignores name mismatch and certificate chain errors, as self signed certs are not signed by the proper CA).

The sample below focuses on Imap class, but exactly the same steps apply to Pop3 and Smtp clients:

C# code

using System.Net.Security;
using System;
using Limilabs.Mail;
using Limilabs.Client.IMAP;

internal class Program
{
    private static void Main(string[] args)
    {
        using (Imap client = new Imap())
        {
            // Use custom certificate validation:
            client.ServerCertificateValidate +=
                new ServerCertificateValidateEventHandler(Validate);

            // Minimalistic version to accept any certificate:
            // 
            // client.ServerCertificateValidate +=
            //    (sender, e) => { e.IsValid = true; };

            client.ConnectSSL("server.example.com");
            client.UseBestLogin("user", "password");

            foreach (long uid in client.GetAll())
            {
                var eml = client.GetMessageByUID(uid);
                IMail email = new MailBuilder()
                    .CreateFromEml(eml);

                Console.WriteLine("subject: {0}", email.Subject);
            }

            client.Close();
        }
    }

    private static void Validate(
        object sender,
        ServerCertificateValidateEventArgs e)
    {
        const SslPolicyErrors ignoredErrors =
            // self-signed
            SslPolicyErrors.RemoteCertificateChainErrors
            // name mismatch
            |  SslPolicyErrors.RemoteCertificateNameMismatch;  

        string nameOnCertificate = e.Certificate.Subject;

        if ((e.SslPolicyErrors & ~ignoredErrors) 
            == SslPolicyErrors.None)
        {
            e.IsValid = true;
            return;
        }
        e.IsValid = false;
    }
} ;

Visual Basic .NET code

Imports System.Net.Security
Imports System
Imports Limilabs.Mail
Imports Limilabs.Client.IMAP

Public Module Module1

  Public Sub Main(ByVal args As String())
    Using client As New Imap()
      ' Use custom certificate validation:
      AddHandler client.ServerCertificateValidate, AddressOf Validate

      client.ConnectSSL("server.example.com")
      client.UseBestLogin("user", "password")

      For Each uid As Long In client.GetAll()
        Dim email As IMail = New MailBuilder().CreateFromEml( _
          client.GetMessageByUID(uid))

        Console.WriteLine("subject: {0}", email.Subject)
      Next

      client.Close()
    End Using
  End Sub

  Private Sub Validate( _
     ByVal sender As Object, _
     ByVal e As ServerCertificateValidateEventArgs)

     Const ignoredErrors As SslPolicyErrors = _
          ' self-signed
          SslPolicyErrors.RemoteCertificateChainErrors _
          ' name mismatch
          Or SslPolicyErrors.RemoteCertificateNameMismatch        

     Dim nameOnCertificate As String = e.Certificate.Subject

      If (e.SslPolicyErrors And Not ignoredErrors) = SslPolicyErrors.None Then
         e.IsValid = True
         Return
      End If
      e.IsValid = False
  End Sub

End Module

Forward an email

If you want to share an email with other parties, forwarding is what you need to do.

There are two ways of forwarding a message:

In this article we’ll describe the first option, in which you insert the original inline in your forward and copy all attachments. You can use Mail.dll to forward both HTML and plain-text emails.

ForwardBuilder class allows you to specify custom HTML and plain-text templates for the forward. Mail.dll will parse the HTML code, extract body part, and build-in template engine will do the rest.

The next great thing is that plain-text version of the email is always generated automatically.

In our example we’ll use Mail.dll .NET IMAP component to download first message from an IMAP server. Then we’ll create new message by using ForwardBuilder class. The sample also shows how to add additional attachments to the forwarded email. Finally we’ll use Mail.dll SMTP client to send this message.

// C#

IMail original = GetFirstMessage();

ForwardBuilder forwardBuilder = original.Forward();

// You can specify your own, custom, body and subject templates:
forwardBuilder.HtmlReplyTemplate = @"<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">
    <html>
    <head>
        <meta http-equiv=""Content-Type"" content=""text/html; charset=UTF-8"" />
        <title>[Subject]</title>
    </head>
    <body>
    [Html]
    <br /><br />
    On [Original.Date] [Original.Sender.Name] wrote:
    <blockquote style=""margin-left: 1em; padding-left: 1em; border-left: 1px #ccc solid;"">
        [QuoteHtml]
    </blockquote>
    </body>
    </html>";
forwardBuilder.SubjectReplyTemplate = "Fw: [Original.Subject]";

forwardBuilder.Html = "Tom, <br/><br/>please resolve this.";

MailBuilder builder = forwardBuilder.Forward(new MailBox("bob@example.org", "Bob"));
builder.To.Add(new MailBox("tom@example.org", "Tom"));

// You can add attachments to forwarded email
//builder.AddAttachment("report.csv");

IMail forward = builder.Create();

using (Smtp smtp = new Smtp())
{
    smtp.Connect("smtp.example.org"); // or ConnectSSL
    smtp.UseBestLogin("user", "password");
    smtp.SendMessage(forward);
    smtp.Close();
}


static IMail GetFirstMessage()
{
    IMail email;
    using (Imap imap = new Imap())
    {
        imap.Connect("imap.example.com"); // or ConnectSSL if you want to use SSL
        imap.UseBestLogin("user", "password");
        List<long> uids = imap.GetAll();
        if (uids.Count == 0)
            throw new Exception("There are no messages");
        var eml = imap.GetMessageByUID(uids[0]); 
        email = new MailBuilder().CreateFromEml(eml);
        imap.Close();
    }
    return email;
}

' VB.NET

Dim original As IMail = GetFirstMessage()

Dim forwardBuilder As ForwardBuilder = original.Forward()

' You can specify your own, custom, body and subject templates:
forwardBuilder.HtmlReplyTemplate = _
"<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">" + _
" <html>" +  _
" <head>" +  _
"    <meta http-equiv=""Content-Type"" content=""text/html; charset=UTF-8"" />" +  _
"    <title>[Subject]</title>" +  _
" </head>" +  _
" <body>" +  _
"  [Html]" +  _
"  <br /><br />" +  _
"  On [Original.Date] [Original.Sender.Name] wrote:" +  _
"  <blockquote style=""margin-left: 1em; padding-left: 1em; border-left: 1px #ccc solid;"">" +  _
"    [QuoteHtml]" +  _
"  </blockquote>" +  _
" </body>" +  _
" </html>"
forwardBuilder.SubjectReplyTemplate = "Fw: [Original.Subject]"

forwardBuilder.Html = "Tom, <br/><br/>please resolve this."

Dim builder As MailBuilder = forwardBuilder.Forward( _
    New MailBox("bob@example.org", "Bob"))
builder.[To].Add(New MailBox("tom@example.org", "Tom"))

' You can add attachments to forwarded email
'builder.AddAttachment("report.csv")

Dim forward As IMail = builder.Create()

Using smtp As New Smtp()
	smtp.Connect("smtp.example.org")
	smtp.UseBestLogin("user", "password") ' or ConnectSSL
	smtp.SendMessage(forward)
	smtp.Close()
End Using

Private Shared Function GetFirstMessage() As IMail
	Dim email As IMail
	Using imap As New Imap()
		imap.Connect("imap.example.com")
		' or ConnectSSL if you want to use SSL
		imap.UseBestLogin("user", "password")
		Dim uids As List(Of Long) = imap.GetAll()
		If uids.Count = 0 Then
			Throw New Exception("There are no messages")
		End If
		Dim eml = imap.GetMessageByUID(uids(0))
		email = New MailBuilder().CreateFromEml(eml)
		imap.Close()
	End Using
	Return email
End Function

In the forward templates (HtmlForwardTemplate, TextForwardTemplate, SubjectForwardTemplate) you have access to following fields:

  • string Subject – subject of the forward (e.g. [Subject])
  • string Text – plain text of the forward (e.g. [Test])
  • string Html – html of the forward (e.g. [Html])
  • string QuoteText – original text quoted using ‘>’ chars (e.g. [QuoteText])
  • string QuoteHtml – body contents of original html or original text converted to html (e.g. [QuoteHtml])
  • IMail Original – original email you are forwarding and all its properties (e.g. [Original.Subject], [Original.Sender.Address])

Please note that you can use any template and data to generate actual forward email (ForwardBuilder.Html and ForwardBuilder.Text).

If you want as little change as possible made to the original email you can use following code:

// C#

IMail original = GetFirstMessage();

original.To.Clear();
original.To.Add(new MailBox("forward@example.org"));

using (Smtp smtp = new Smtp())
{
    smtp.Connect("smtp.example.org"); // or ConnectSSL
    smtp.UseBestLogin("user", "password");
    smtp.SendMessage(original);
    smtp.Close();
}
' VB.NET version

Dim original As IMail = GetFirstMessage()

original.[To].Clear()
original.[To].Add(New MailBox("forward@example.org"))

Using smtp As New Smtp()
	smtp.Connect("smtp.example.org")
	smtp.UseBestLogin("user", "password") ' or ConnectSSL
	smtp.SendMessage(original)
	smtp.Close()
End Using

You can also forward an email as a attachment.

Send email using fluent interface

// C# version

using Fluent = Limilabs.Mail.Fluent;

Fluent.Mail.Html(@"Html with an image: <img src=""cid:lena"" />")
  .AddVisual(@"c:lena.jpeg").SetContentId("lena")
  .AddAttachment(@"c:tmp.doc").SetFileName("document.doc")
  .To("to@mail.com")
  .From("from@mail.com")
  .Subject("Subject")
  .UsingNewSmtp()
  .Server("smtp.example.org")
  .WithSSL()
  .WithCredentials("user", "password")
  .Send();
' VB.NET version

Imports Fluent = Limilabs.Mail.Fluent;

Fluent.Mail.Html("Html with an image: <img src=""cid:lena"" />") _
  .AddVisual("c:lena.jpeg").SetContentId("lena") _
  .AddAttachment("c:tmp.doc").SetFileName("document.doc") _
  .[To]("to@mail.com") _
  .From("from@mail.com") _
  .Subject("Subject") _
  .UsingNewSmtp() _
  .Server("smtp.example.org") _
  .WithSSL() _
  .WithCredentials("user", "password") _
  .Send()

Fluent interface for creating and sending emails was added to Mail.dll as an additional feature.

You can still use MailBuilder class to create emails.
Note that error handling code was removed for simplicity, you should use try…catch block when sending.

If your server does not require authentication or SSL simply skip WithSSL and WithCredentials methods:

// C# version

Mail.Text("Hi there")
    .Subject("Hi")
    .To("to@mail.com")
    .From("from@example.org")
    .UsingNewSmtp()
    .Server("smtp.example.org")
    .Send();
' VB.NET version

Mail.Text("Hi there") _
  .Subject("Hi") _
  .[To]("to@mail.com") _
  .From("from@example.org") _
  .UsingNewSmtp() _
  .Server("smtp.example.org") _
  .Send()

Same code using MailBuilder:

// C# version

MailBuilder builder = new MailBuilder();
builder.Text = "Hi there";
builder.Subject = "Hi";
builder.To.Add(new MailBox("to@mail.com"));
builder.From.Add(new MailBox("from@example.org"));
IMail email= builder.Create();

using(Smtp smtp = new Smtp())
{
    smtp.Connect("smtp.example.org"); // or ConnectSSL
    // smtp.UseBestLogin("user", "password");
    smtp.SendMessage(email);
    smtp.Close();
}
' VB.NET version

Dim builder As New MailBuilder()
builder.Text = "Hi there"
builder.Subject = "Hi"
builder.[To].Add(New MailBox("to@mail.com"))
builder.From.Add(New MailBox("from@example.org"))

Dim emailAs IMail = builder.Create()

Using smtp As New Smtp()
    smtp.Connect("smtp.example.org") ' or ConnectSSL
    ' smtp.UseBestLogin("user", "password")
    smtp.SendMessage(email)
    smtp.Close()
End Using

You can also reuse existing Smtp connection to send multiple emails using fluent interface:

// C# version

using(Smtp smtp = new Smtp())
{
    smtp.Connect("smtp.example.org"); // or ConnectSSL
    smtp.UseBestLogin("user", "password");

    Mail.Text("Hi there")
        .Subject("Hi")
        .To("to@mail.com")
        .From("from@example.org")
        .Send(smtp);

    // Send more emails here...

    smtp.Close();
}
' VB.NET version

Using smtp As New Smtp()
	smtp.Connect("smtp.example.org") ' or ConnectSSL
	smtp.UseBestLogin("user", "password")

	Mail.Text("Hi there") _
          .Subject("Hi") _
          .[To]("to@mail.com") _
          .From("from@example.org") _
          .Send(smtp)

	' Send more emails here...

	smtp.Close()
End Using

Send raw data (*.eml file)

This post describes how to send raw eml email data as email message using SMTP server.

In most cases you don’t need to send raw eml data.
Take a look at those topics, they may be better describing your needs:

*.eml extension is a standard extension used for storing email files. Eml file contains raw data received from POP3 or IMAP server. You can use GetMessageByUID on Pop3 or Imap class to obtain it. It can be also created using IMail.Render method:

MailBuilder builder = new MailBuilder();
builder.Subject = "Test";
builder.Text = "This is plain text message.";
builder.From.Add(new MailBox("alice@mail.com", "Alice"));
builder.To.Add(new MailBox("bob@mail.com", "Bob"));
IMail email = builder.Create();
byte[] eml = email.Render();

Eml file includes all attachments, visual elements, email body in text, HTML (if defined) formats and email headers (such as: from, to, subject, date and so on).

When sending email message using SMTP protocol you must fill three SmtpMail class properties:

  • From – FROM command dialogue
  • To – RCPT TO command in SMTP dialogue
  • RawEmlData – DATA command in SMTP dialogue

As you can see both ‘from address’ and ‘recipient’ are duplicated – they also appear in eml data as email From and To headers. SmtpMail has helper methods, such as CreateFromEmlFile or CreateFromEml that parse eml data and fill all properties required for SMTP communication.

// C# version

using Limilabs.Client.SMTP;

class Program
{
    static void Main(string[] args)
    {
        using (Smtp smtp = new Smtp())
        {
            smtp.Connect("server.company.com");
            smtp.UseBestLogin("user", "password");

            SmtpMail smtpMail = SmtpMail.CreateFromEmlFile(@"c:\email.eml");

            smtp.SendMessage(smtpMail);
            smtp.Close();
        }
    }
};
' VB.NET version

Imports Limilabs.Client.SMTP

Public Module Module1
    Public Sub Main(ByVal args As String())
        Using smtp As New Smtp()
            smtp.Connect("server.company.com")
            smtp.UseBestLogin("user", "password")

            Dim smtpMail As SmtpMail = smtpMail.CreateFromEmlFile("c:\email.eml")

            smtp.SendMessage(SmtpMail)
            smtp.Close()
        End Using
    End Sub
End Module

Send HTML email

In this article we’ll show how to create and send HTML email message with embedded image.

As a prerequisite you need to add reference to Mail.dll .NET email component to your project.

First we’ll learn some basics of HTML syntax used in emails. Especially how to reference image attached to the message from the HTML content. We use cid protocol to do that:

<img src = 'cid:image1' />

What comes after “cid:” is the Content-ID of the referenced visual object. This object must be attached to the email.

As always, when we need to create email message, we use MailBuilder class. We need to set Html property with the HTML data. It is always good to send emails both in HTML and plain text formats. Good thing is, that Mail.dll automatically extracts plain text data from HTML content when Html property is set.

MailBuilder builder = new MailBuilder();
builder.Html =                            // Set HTML body
            "This is <strong>HTML</strong> message, " +
            "with embedded image:<br />" +
            "<img src = 'cid:image1' />.";

Next thing we need to do is to attach the image. We’ll use AddVisual method for that – it adds visual element to the email MIME tree. AddVisual has few overloads that allow to add MIME objects from memory stream, byte array or from disk.

Remember to set ContentId property for added visual objects (E.g. image.ContentId = “image1”).

MimeData image = builder.AddVisual(@"c:\image.jpg");
image.ContentId = "image1";

Final step is to connect to SMTP server and send the message. Use Connect(string host) method to establish connection – it uses standard SMTP server port: 587. You can use Connect(string host, int port) overload, if you need to specify different port (for example 25). If your server requires SSL use ConnectSSL method (Here you can find more info on using SMTP with SSL).

Here’s the entire sample:

// C# version

using System;
using Limilabs.Mail;
using Limilabs.Mail.MIME;
using Limilabs.Mail.Headers;
using Limilabs.Client.SMTP;

class Program
{
    static void Main(string[] args)
    {
        // Use builder class to create new email message
        MailBuilder builder = new MailBuilder();
        builder.From.Add(new MailBox("alice@mail.com", "Alice"));
        builder.To.Add(new MailBox("bob@mail.com", "Bob"));
        builder.Subject = "This is HTML test";

        builder.Html =                            // Set HTML body
            "This is <strong>HTML</strong> message, " +
            "with embeddedimage:<br />" +
            "<img src = 'cid:image1' />.";

        // Read attachment from disk...and add it to Visuals collection
        MimeData image = builder.AddVisual(@"c:\image.jpg");
        image.ContentId = "image1";

        IMail email = builder.Create();

        // Send the message
        using (Smtp smtp = new Smtp())
        {
            smtp.Connect("server.example.com");   // or ConnectSSL for SSL
            smtp.UseBestLogin("user", "password"); // remove if not needed

            smtp.SendMessage(email);

            smtp.Close();
        }
    }
};
' VB.NET version

Imports Limilabs.Client.SMTP
Imports Limilabs.Mail
Imports Limilabs.Mail.MIME
Imports Limilabs.Mail.Headers

Public Module Module1
    Public Sub Main(ByVal args As String())

        ' Use builder class to create new email message
        Dim builder As New MailBuilder()
        builder.From.Add(New MailBox("alice@mail.com", "Alice"))
        builder.[To].Add(New MailBox("bob@mail.com", "Bob"))
        builder.Subject = "This is HTML test"

        ' Set HTML body
        builder.Html = "This is <strong>HTML</strong> message, " _
                            + "with embeddedimage:<br />" _
                            + "<img src = 'cid:image1' />."

        ' Read attachment from disk...and add it to Visuals collection
        Dim image As MimeData = builder.AddVisual("c:\image.jpg")
        image.ContentId = "image1"

        Dim email As IMail = builder.Create()

        ' Send the message
        Using smtp As New Smtp()
            smtp.Connect("server.example.com")    ' or ConnectSSL for SSL
            smtp.UseBestLogin("user", "password")   ' remove if not needed

            smtp.SendMessage(email)

            smtp.Close()
        End Using

    End Sub
End Module