Download email attachments in .NET

First you’ll need an IMAP client or POP3 client to download emails from the server.

The email attachments are downloaded along with the email message. Attachments are stored within the email as part of a mime tree. Usually Quoted-Printable or Base64 encoding is used. Mail.dll is going to parse such tree for you and expose all attachments as well-known .NET collections.

IMail uses 3 collections for storing attachments:

  • IMail.Attachments – contains all attachments (this includes Visuals and NonVisuals),
  • IMail.Visuals – contains files that should be displayed to the user (usually images embedded in HTML emails).
  • IMail.NonVisuals – ‘real’ attachments.

Below you’ll find samples of how you can save all attachments to disk using C# and VB.NET via POP3 and IMAP protocols.

Download attachments from IMAP server

// C#

using(Imap imap = new Imap())
{
	imap.Connect("imap.example.com");   // or ConnectSSL for SSL
	imap.UseBestLogin("user", "password");

	imap.SelectInbox();
	List<long> uids = imap.SearchFlag(Flag.All);

	foreach (long uid in uids)
	{
		IMail email = new MailBuilder()
			.CreateFromEml(imap.GetMessageByUID(uid));

		Console.WriteLine(email.Subject);

		// save all attachments to disk
		foreach(MimeData mime in email.Attachments)
		{
			mime.Save(mime.SafeFileName);
		}
	}
	imap.Close();
}
' VB.NET

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

	imap.SelectInbox()
	Dim uids As List(Of Long) = imap.SearchFlag(Flag.All)

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

		Console.WriteLine(email.Subject)

		' save all attachments to disk
		For Each mime As MimeData In email.Attachments
			mime.Save(mime.SafeFileName)
		Next
	Next
	imap.Close()
End Using

Download attachments from POP3 server

// C# 

using(Pop3 pop3 = new Pop3())
{
	pop3.Connect("pop3.example.com");   // or ConnectSSL
	pop3.UseBestLogin("user", "password");

	foreach (string uid in pop3.GetAll())
	{
		IMail email = new MailBuilder()
			.CreateFromEml(pop3.GetMessageByUID(uid));

		Console.WriteLine(email.Subject);

		// save all attachments to disk
		foreach(MimeData mime in email.Attachments)
		{
			mime.Save(mime.SafeFileName);
		}
	}
	pop3.Close();
}
' VB.NET

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

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

		Console.WriteLine(email.Subject)

		' save all attachments to disk
		For Each mime As MimeData In email.Attachments
			mime.Save(mime.SafeFileName)
		Next
	Next
	pop3.Close()
End Using

You can also save attachment to stream (using MimeData.Save(Stream stream) method), get direct access to attachments data as stream (using MemoryStream MimeData.GetMemoryStream() method) or as byte array (using byte[] MimeData.Data).

Tags: , ,

24 Responses to “Download email attachments in .NET”

  1. Vincentius Owen Says:

    Is it possible for me to delete specified email with this component?

    Thank You

  2. Limilabs support Says:

    @Vincentius Yes, you can. Both IMAP and POP3 clients have two methods: DeleteMessage and DeleteMessageByUID.

    If you are using Gmail you may want to also check this post:
    http://www.limilabs.com/blog/delete-email-permanently-in-gmail

  3. Franz Says:

    When i try the “when using pop3 sever” for C# and i keep getting the System.UnauthorizedAccessException was unhandled error. Any fixes?

  4. Limilabs support Says:

    @Franz
    1. Are you using the latest version?
    2. What is the stack trace of the exception?
    3. Please contact us via email:
    http://www.limilabs.com/support
    it’ll be much easier to help you.

  5. madhan Says:

    email.Attachments.ForEach(mime => mime.Save(mime.SafeFileName));

    “=>” showing error

  6. Limilabs support Says:

    @madhan

    Lambda expressions are supported in C# compiler 3.0 or greater .

    You can use regular foreach loop to iterate over Attachments collection.

  7. Sunil Says:

    Hi,

    Where I can change folder path for download attachments from POP3?
    What is default path?
    It’s working but i can’t able to see the download attachemnts
    Please replay

  8. Limilabs support Says:

    @Sunil
    Attachments are part of the email you download, files are not created on disk until you call MimeData.Save method on objects in Attachments collection.

    If you want to specify different folder than the default path for current process, just specify it as an argument for the Save method:

    mime.Save(@”c:\attachments\” + mime.SafeFileName)

  9. Chintan Says:

    Hi,

    I want to download .csv format file and save it to database.

    so how can i do it ???

    I dont want to save the csv format file in any harddrive.

    Please Reply.

  10. Limilabs support Says:

    @Chintan

    If the csv file is attached to the email you can directly access attachment’s data as stream using MimeData.GetMemoryStream() method:

    MemoryStream stream = mime.GetMemoryStream();
    

    or as byte array using MimeData.Data property:

    byte[] data = mime.Data;
    

    If your csv attachment has correct mime type, you can also cast MimeData to MimeText and use Text property to access csv data as string:

    string text = ((MimeText)mime).Text;
    

    As for your question on how to save this data to database, it depends on the db you are using (MSSQL, Oracle, MySql, document db) and it’s structure. I don’t think I can help you with so little information you provided and also I believe it’s out of scope of Mail.dll.

  11. Binis Says:

    How can I check if the password that a user has entered matches to its username (basically if it is correct)…..

    Thanks,
    Binis

  12. Limilabs support Says:

    @Binis Server does that.
    If the password is incorrect you’ll get an exception from Login method.

  13. Kent Says:

    What if there are multiple files in the emails, I cannot figure out how to save them all?

    Thanks,
    Kent

  14. Limilabs support Says:

    @Kent

    You should iterate over Attachments collection as shown in the blog post,
    you can use foreach loop if you are not familiar with lambdas:

    foreach (MimeData attachment in email.Attachments)
    {
        attachment.Save("c:\" + attachment.SafeFileName);
    }
    
  15. mojtaba Says:

    files don’t save completely, size of downloaded files is zero.

  16. Limilabs support Says:

    @mojtaba

    Please be more specific. If you have problems parsing the message please follow the steps here: http://www.limilabs.com/blog//i-have-problems-parsing-the-message and contact us directly.

  17. Veincorp Says:

    I purchased your mail.dll, it’s awsome, But Why downloaded visual image saved in .DAT extension, is there any way to save it in proper extension

  18. Limilabs support Says:

    @Veincorp

    Most likely the sender of the message have not specified the filename at all.
    In such case SafeFileName property (which you probably use with Save method) generates unique filename.

    You can of course check FileName property for null and act according to your needs.

  19. Lax Says:

    I have set up a IMAP gmail account
    I am trying to connect with the code :

    using (Imap imap = new Imap())
    {
    imap.Connect(“smtp.gmail.com”);
    imap.UseBestLogin(“imap.dmtrigger@gmail.com”, “password”);
    imap.SelectInbox();
    ….
    ….

    But I get this error :
    “A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond …. ”

    Would this be the problem with the account ? But I can send and recieve mails from the account I have set up in my Outlook.
    Can anyone help?

    Thanks,
    Lax.

  20. Limilabs support Says:

    @Lax,

    1. When using IMAP protocol use IMAP server: imap.gmail.com
    2. Use SSL

    using (Imap client = new Imap())
    {
        client.ConnectSSL("imap.gmail.com");
        client.Login("user@gmail.com", "password");
        client.SelectInbox();
    
        // ...
    
        client.Close();
    }
    
  21. Rajkumar Says:

    Error 1 The type or namespace name ‘Imap’ could not be found (are you missing a using directive or an assembly reference?)

  22. Limilabs support Says:

    @Rajkumar

    You need to download and add a reference to Mail.dll IMAP library:
    http://www.limilabs.com/mail/download

  23. Archana Says:

    Hi,

    Your dll is great, but there is a problem that I am facing.
    I have added the save attachment option on a button click event:


    pop3.ConnectSSL("pop.gmail.com");
    pop3.UseBestLogin("username", "password");

    IMail email = new MailBuilder().CreateFromEml(
    pop3.GetMessageByUID(lst.SelectedValue));

    foreach (MimeData attachment in email.Attachments)
    {
    if (attachment.FileName == lblAttachment.Text)
    {
    attachment.Save("c:\\" + attachment.SafeFileName);
    }
    }
    pop3.Close();

    but I get a error message that the UID does not exists, and also how do I access the sent mails (sent items)

  24. Limilabs support Says:

    @Archana,

    > I get a error message that the UID does not exists
    Most likely you are trying to download this message for a second time.
    Gmail’s POP3 behavior is quite different from other POP3 servers (http://www.limilabs.com/blog/gmail-pop3-behavior)
    I strongly advise you to use IMAP, it’s going to by much easier for you and you’ll be able to access other folders.

    To access different folder than Inbox you need to use IMAP protocol:
    http://www.limilabs.com/blog/folder-access-with-imap

Leave a Reply