Send email with attachment

In this article we’ll create and send email with an attachment.

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

We’ll use MailBuilder class to create email message. This will be plain text message sent from Alice to Bob:

MailBuilder builder = new MailBuilder();
builder.From.Add(new MailBox("alice@mail.com", "Alice"));
builder.To.Add(new MailBox("bob@mail.com", "Bob"));
builder.Subject = "Test";
builder.Text = "This is plain text message.";

You use AddAttachment method to add new attachment to the email, it returns MimeData class instance, that can by used to change/set file name, data, content-id, or any other MIME header. This method has 3 overloads, that allow to create and add attachment from file, byte array or add existing MimeData object as email attachment. In our sample we’ll create attachment from file located on disk.

MimeData attachment = builder.AddAttachment(@"../image.jpg");

Mail.dll email component automatically recognizes content type using file extension. When you create attachment using byte array or MemoryStream, you can use ContentType property to set it manually:

attachment.ContentType = ContentType.ImageJpeg;

Finally we’ll use Smtp component to connect to SMTP server and send your message.

Following is the entire sample, that creates new email message, adds attachment from file located on disk. Than it connects to specified SMTP server and sends the message. Please note that some error handling is missing for simplicity and you should examine ISendMessageResultresult object returned by SendMessage to be sure that email sending was successful.

// C# version

using System;
using Limilabs.Mail;
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 = "Test";
        builder.Text = "This is plain text message.";

        // Read attachment from disk, add it to Attachments collection
        MimeData attachment = builder.AddAttachment(@"../image.jpg");

        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 = "Test"
        builder.Text = "This is plain text message."

        ' Read attachment from disk, add it to Attachments collection
        Dim attachment As MimeData = builder.AddAttachment("../image.jpg")

        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

Issue a custom command to POP3 server

You can send any command to POP3 server using Mail.dll and receive servers’s response easy.

In this example we will issue LIST command. LIST command is used to check the email size without downloading it from the POP3 server.

There are 2 versions of the LIST command. First takes message number parameter:

LIST messageNumber

We are asking for specific message here, which means that we expect to receive single line response.

Remember that message numbers on POP3 servers start from 1.

// C# version

using System;
using Limilabs.Client.POP3;

class Program
{
    static void Main(string[] args)
    {
        using (Pop3 pop3 = new Pop3())
        {
            pop3.Connect("server.example.com");
            pop3.Login("user", "password");

            Pop3Response response = pop3.SendCommand("LIST " + 1);

            // We expect string in following format: "0 32768"
            string sizeInBytes = response.Message.Split(' ')[1];

            Console.WriteLine(sizeInBytes);
            pop3.Close();
        }
    }
};
' VB.NET version

Imports System
Imports Limilabs.Client.POP3

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

        Using pop3 As New Pop3()
            pop3.Connect("server.example.com")
            pop3.Login("user", "password")

            Dim response As Pop3Response = pop3.SendCommand("LIST " + 1)

            ' We expect string in following format: "0 32768"
            Dim sizeInBytes As String = response.Message.Split(" "c)(1)

            Console.WriteLine(sizeInBytes)
            pop3.Close()
        End Using

    End Sub
End Module

Second version is LIST command without any arguments:

LIST

It gets the size of every message that is currently stored on the POP3 server – server replies with multi-line response:

// C# version

using System;
using Limilabs.Mail;
using Limilabs.Client.POP3;

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

            Pop3Response response = pop3.SendMultiLineCommand("LIST");

            foreach(string line in response.GetLines())
            {
                // We expect following format: "0 32768"
                string[] tmp = line.Split(' ');
                Console.WriteLine("Message number {0} is {1} bytes long.",
                                  tmp[0],
                                  tmp[1]);
            }
            pop3.Close();
        }
    }
};

' VB.NET version

Imports System
Imports Limilabs.Client.POP3

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

        Using pop3 As New Pop3()
            pop3.Connect("server.company.com")
            pop3.Login("user", "password")

            Dim response As Pop3Response = pop3.SendMultiLineCommand("LIST")

            For Each line As String In response.GetLines()
                ' We expect following format: "0 32768"
                Dim tmp As String() = line.Split(" "c)
                Console.WriteLine("Message number {0} is {1} bytes long.", tmp(0), tmp(1))
            Next
            pop3.Close()
        End Using

    End Sub
End Module


Access custom email header using POP3

Most common email headers like From, Subject, Date, To, Cc etc. are exposed by IMail interface as properties. Those properties contain parsed information and return strong typed objects like DateTime‘s, string collections, MailAddress collections.

There are times however that you need to access non-standard email header. Good example is a need to get a spam value that your POP3 server assigns to every email by inserting additional ‘x-spam’ header.

For this purpose you can always use IMail.Document.Root.Headers collection to access any non-standard and standard header.

If you only need to access email headers consider using GetHeadersByUID method which doesn’t download entire message, but only headers. It uses POP3 TOP command. The sample below downloads entire message.

// C# version

using System;
using Limilabs.Mail;
using Limilabs.Client.POP3;

class Program
{
    static void Main(string[] args)
    {
        using (Pop3 pop3 = new Pop3())
        {
            pop3.Connect("pop3.example.com");    // or ConnectSSL for SSL
            pop3.UseBestLogin("user", "password");

            MailBuilder builder = new MailBuilder();
            foreach (string uid in pop3.GetAll())
            {
                var eml = pop3.GetMessageByUID(uid);
                IMail email = builder.CreateFromEml(eml);
                Console.WriteLine("subject: {0}", email.Subject);

                // Get custom header:
                string header = email.Document.Root.Headers["x-spam"];
                Console.WriteLine("x-spam: {0}", header);
            }
            pop3.Close();
        }
    }
};

' VB.NET version

Imports System
Imports Limilabs.Mail
Imports Limilabs.Client.POP3

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

        Using pop3 As New Pop3()
            pop3.Connect("pop3.example.com")    ' or ConnectSSL for SSL
            pop3.UseBestLogin("user", "password")

            Dim builder As New MailBuilder()
            For Each uid As String In pop3.GetAll()
                Dim eml = pop3.GetMessageByUID(uid)
                Dim email As IMail = builder.CreateFromEml(eml)
                Console.WriteLine("subject: {0}", email.Subject)

                ' Get custom header:
                Dim header As String = email.Document.Root.Headers("x-spam")
                Console.WriteLine("x-spam: {0}", header)
            Next
            pop3.Close()
        End Using

    End Sub
End Module

Get email headers using POP3 (TOP command)

The POP3 protocol’s TOP command is useful to download only headers of the big email message, without actually downloading entire message including all attachments. With Mail.dll POP3 component it is easy to use TOP command, you simply invoke one of the GetHeadersBy method.

// C# version

using System;
using Limilabs.Mail;
using Limilabs.Client.POP3;

class Program
{
    static void Main(string[] args)
    {
        using (Pop3 pop3 = new Pop3())
        {
            pop3.Connect("pop3.example.com");    // or ConnectSSL
            pop3.Login("user", "password");

            MailBuilder builder = new MailBuilder();
            foreach (string uid in pop3.GetAll())
            {
                var headers = pop3.GetHeadersByUID(uid);
                IMail email = builder.CreateFromEml(headers);

                Console.WriteLine("subject: {0}", email.Subject);
            }
            pop3.Close();
        }
    }
}
' VB.NET version

Imports System
Imports Limilabs.Mail
Imports Limilabs.Client.POP3

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

        Using pop3 As New Pop3()
            pop3.Connect("pop3.example.com")    ' or ConnectSSL
            pop3.Login("user", "password")

            Dim builder As New MailBuilder()
            For Each uid As String In pop3.GetAll()
                Dim headers = pop3.GetHeadersByUID(uid)
                Dim email As IMail = builder.CreateFromEml(headers)

                Console.WriteLine("subject: {0}", email.Subject)
            Next
            pop3.Close()
        End Using

    End Sub
End Module

Login to POP3 server in using APOP

APOP is a secure method of logging in to a POP3 mail server. Your password is encrypted while being transmitted over the network. Not all servers support APOP. The ‘HasTimeStamp’ property usually tells that your server supports it.

// C# version

using System;
using Limilabs.Mail;
using Limilabs.Client.POP3;

class Program
{
    static void Main(string[] args)
    {
        using (Pop3 pop3 = new Pop3())
        {
            pop3.Connect("server.example.com");

            if (pop3.HasTimeStamp == true)
                pop3.LoginAPOP("user", "password");
            else
                pop3.Login("user", "password");

            // Receive all messages and display the subject
            MailBuilder builder = new MailBuilder();
            foreach (string uid in pop3.GetAll())
            {
                IMail email = builder.CreateFromEml(
                    pop3.GetMessageByUID(uid));

                Console.WriteLine("subject: {0}", email.Subject);
            }
            pop3.Close();
        }
    }
};
' VB.NET version

Imports System
Imports Limilabs.Mail
Imports Limilabs.Client.POP3

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

        Using pop3 As New Pop3()
            pop3.Connect("server.example.com")

            If pop3.HasTimeStamp = True Then
                pop3.LoginAPOP("user", "password")
            Else
                pop3.Login("user", "password")
            End If

            ' Receive all messages and display the subject
            Dim builder As New MailBuilder()
            For Each uid As String In pop3.GetAll()
                Dim email As IMail = builder.CreateFromEml( _
                    pop3.GetMessageByUID(uid))

                Console.WriteLine("subject: {0}", email.Subject)
            Next
            pop3.Close()
        End Using

    End Sub
End Module