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 HTM content when Html property is set.

MailBuilder builder = new MailBuilder();
builder.Html =                            // Set HTML body
            "This is <strong>HTML</strong> message, " +
            "with embeddedimage:<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

Tags: , , ,

11 Responses to “Send HTML email”

  1. lana Says:

    Hi,
    Very impressed so far. One question: how do I send RichTextBox contents from my form? Html sends straight mail, Text property just garbles everything up (shows all RTF code in text). Any insight would be appreciated.

  2. Limilabs support Says:

    @Lana

    You can use AddAlternative method:

    MailBuilder builder = new MailBuilder();
    builder.Text = "plain text";
    var rtf = new MimeFactory().CreateMimeText();
    rtf.ContentType = new ContentType(MimeType.Text, MimeSubtype.Rtf);
    rtf.Text = @"{rtf1ansideff0
    {colortbl;red0green0blue0;red255green0blue0;}
    This line is the default colorline
    cf2
    This line is redline
    cf1
    This line is the default color
    }";
    builder.AddAlternative(rtf);
    IMail mail = builder.Create();
    

    Please note that not all email clients support and are able to display RTF formatted email.

  3. lana Says:

    Thanks,
    I am sorry, I should have been more specific: I am using vb.net (very new at it). I’ve tried to translate it:

    Dim rtf = New MimeFactory().CreateMimeText()
    rtf.ContentType = New ContentType(MimeType.Text, MimeSubtype.Rtf)
    rtf.Text = RichTextBox1.Text
    builder.AddAlternative(rtf)

    Dim email As IMail = builder.Create()

    but it did not work for me, it just attached a plane text file ‘noname’ to the email. I must be doing it wrong…

  4. Limilabs support Says:

    @lana

    1.
    [from msdn]
    The Text property does not return any information about the formatting applied to the contents of the RichTextBox.
    To get the rich text formatting (RTF) codes, use the Rtf property.

    2.
    Are you sure that your email client supports rtf content?
    What email client are you using?

  5. lana Says:

    Thanks again.
    Using AddAlternative method with Rtf property just garbled the message, but I found a neat conversion function at http://www.codeproject.com/KB/string/EasyRTF_To_HTML_.aspx
    so I reverted back to Html property:

    builder.Html = sRTF_To_HTML(RichTextBox1.Rtf);

    and it worked like a charm! Thanks again.

  6. Aneesh Kumar Says:

    I need to sent the MailBuilder dataobject filled form Client and sent to server through WebServices. But I am getting the error saying “There was an error reflecting property ‘MailBuilder'”.
    There was an error reflecting type ‘Limilabs.Mail.MailBuilder’.
    Limilabs.Mail.Headers.ContentType cannot be serialized because it does not have a parameterless constructor.

    Any help is appreciated

  7. Limilabs support Says:

    @Aneesh,

    1. MailBuilder class is not indented to be serialized, or transferred between client and server.
    2. Classes, such as ContentType, MimeType can not have default constructor, so XML serialization won’t work for them.
    3. There are properties with type of interface (such as IList) on MailBuilder, which will also prevent serialization.
    4. It is not possible (not secure) to transfer certificate classes, used for signing or encrypting emails, between two machines.

    The bottom line is: use MailBuilder to create or parse emails, but don’t use it as a data transfer object (DTO) – it was not designed for this purpose.

  8. Aneesh Kumar Says:

    We were trying to send email using the Limilabs Mail.dll.
    Below is the snippet we are using to send an E-mail

    using (Smtp smtp = new Smtp())
    {
        smtp.Connect("smtp.gmail.com", 587);                 
        smtp.StartTLS();
        smtp.LoginOAUTH2(from, accessToken);
        SendMessageResult result = smtp.SendMessage(email);
        smtp.Close();
    }
    

    It takes 6 to 7 second to send E-mail which is a worry. Could you let us know what could be the reason. If we purchase will this speed be better.

    Regards,
    Aneesh Kumar

  9. Limilabs support Says:

    @Aneesh,

    Which part takes so long? OAuth2? Are you reusing Smtp object?
    Could it be that this is a problem with your network? Gmail server? Gmail is known for enforcing many limits on its users.

    I don’t believe that this is the problem with Mail.dll – its speed is up to 230 ms/100 emails (local server). Generally on production servers its much less than 200ms/email (around 20-50ms)

    The only “problem” I can see in your code is, that you can use ConnectSSL instead of Connect and StartTLS sequence:

    smtp.ConnectSSL("smtp.gmail.com");
    
  10. Aneesh Kumar Says:

    The subsequent calls takes 2 seconds to sent mail which is fine.
    But for our case every time the access token changes. So whenever we sent a message we need to do this LoginOAUTH2 as below. But this gives an exception saying “No identity changes permitted. im2sm50492321pbd.31 – gsmtp”

    using(Smtp smtp = new Smtp())
    {
        smtp.ConnectSSL("smtp.gmail.com");
        for (int i = 0; i < 5; i++)
        {
            smtp.LoginOAUTH2(from, accesstoken);  // this gives an exception 
            SendMessageResult result = smtp.SendMessage(email);
        }
        smtp.Close()
    }
    

    Regards,
    Aneesh Kumar.

  11. Limilabs support Says:

    @Aneesh

    It is Gmail that takes that much time, please contact their support, if you believe it should act faster.

    “No identity changes permitted. im2sm50492321pbd.31 – gsmtp” error

    This error is generated by the server.

    You can login to the server only once. Which means that you need a separate connection for every user you try to login as. Please note that this is not Mail.dll’s limitation nor bug – this is how SMTP protocol, and in fact all mail protocols, work.

    Only advice I have for you is to create multiple threads, each with its own Smtp class instance, and send several emails through Gmail simultaneously.

Questions?

Consider using our Q&A forum for asking any questions.