Replace attachments in email message

Attachments are not stored separately from message text and headers – they are embedded inside an email message. This, along with inefficient Base64 encoding is the most important reason of email messages being large in size. Mail.dll provides an easy way to replace attachments in existing messages:

// C#

IMail email = new MailBuilder().CreateFromEml(eml);
email.ReplaceAttachments();

' VB.NET

Dim email As IMail = New MailBuilder().CreateFromEml(eml)
email.ReplaceAttachments()

Each attachment will be replaced with the following text information: “This file (‘[FileName]’) containing [Size] bytes of data was removed.”. Thus making email much smaller in size.

ReplaceAttachmentsmethod has an overloaded version, that allows you to skip visual elements (content-disposition: inline) or/and alternative email representations. It also allows to specify text template and custom Tag, that can be used, for example, to create a custom url. This url can point to a place to which attachment was moved.

Within the template you can use [FileName], [Size] and [Tag] as template placeholders.

// C#

IMail email = Limilabs.Mail.Fluent.Mail
    .Text("body")
    .AddAttachment(new byte[] { 1, 2, 3 })
    .SetFileName("report.pdf")
    .Create();

AttachmentReplacerConfiguration configuration = new AttachmentReplacerConfiguration();
configuration.ReplaceVisuals = false;
configuration.Tag = 
    att => "http://example.com/" + email.MessageID + "/" + att.FileName;
configuration.Template = 
    "Attachment [FileName] removed. You can download it here: [Tag]";

email.ReplaceAttachments(configuration);
' VB.NET

Dim email As IMail = Limilabs.Mail.Fluent.Mail _
    .Text("body") _
    .AddAttachment(New Byte() {1, 2, 3}) _
    .SetFileName("report.pdf") _
    .Create()

Dim configuration As New AttachmentReplacerConfiguration()
configuration.ReplaceVisuals = False
configuration.Tag = Function(att)
    Return "http://example.com/" + email.MessageID + "/" + att.FileName
    End Function
configuration.Template = _
    "Attachment [FileName] removed. You can download it here: [Tag]"

email.ReplaceAttachments(configuration)

The following example illustrates the full process of downloading email from IMAP server,
creating new email, with the same information, but with all attachments replaced, uploading this message, and deleting original one:

// C#

using(Imap imap = new Imap())
{
    imap.ConnectSSL("imap.example.org");
    imap.UseBestLogin("user", "password");
    imap.SelectInbox();

    foreach (long uid in imap.GetAll())
    {
        var eml = imap.GetMessageByUID(uid);
        IMail email = new MailBuilder().CreateFromEml(eml);
        if (email.Attachments.Count > 0)
        {
            email.ReplaceAttachments();

            imap.UploadMessage(email);

            imap.DeleteMessageByUID(uid);
        }
    }
    imap.Close();
}
' VB.NET

Using imap As New Imap()
   imap.ConnectSSL("imap.example.org")
   imap.UseBestLogin("user", "password")
   imap.SelectInbox()

   For Each uid As Long In imap.GetAll()
      Dim eml = imap.GetMessageByUID(uid)
      Dim email As IMail = New MailBuilder().CreateFromEml(eml)
      If email.Attachments.Count > 0 Then
         email.ReplaceAttachments()

         imap.UploadMessage(email)

         imap.DeleteMessageByUID(uid)
      End If
   Next
   imap.Close()
End Using

Tags:      

Questions?

Consider using our Q&A forum for asking questions.

4 Responses to “Replace attachments in email message”

  1. Niet Says:

    Tried to read a line. Only ” received.
    I can Connect the smtp server
    but I can’t login it smtp.UseBestLogin(account, password);
    system throw a exception “Tried to read a line. Only ” received.” .
    The Smtp Address and account and password are right.
    And the Smtp server need smtp authentication

  2. Limilabs support Says:

    @Niet,

    If you are using Mail For Windows Store you must use await before ConnectSSL and Connect. Make sure that antivirus and firewall software are disabled. You can read more here: http://www.limilabs.com/blog/tried-to-read-a-line-only-received

  3. PJ Says:

    I would like to store draft email in database in eml format.

    For reload the draft eml I using the mailbuilder:
    imail = mailbuilder.CreateFromEml(Communication.CommunicationContent)

    How to change (add/delete) a attachment in the imail?

  4. Limilabs support Says:

    @PJ,

    In general IMail object shouldn’t be modified. You can however create a MailBuilder from IMail instancs – use IMail.ToBuilder() method. Then you can modify its NonVisuals, Visuals, Alternatives and Attachments collections.