How to search IMAP in .NET
One of many advantages IMAP protocol has over POP3 protocol is the ability to search.
There are several ways of performing search using Mail.dll .NET IMAP library:
- Search(Flag) – for common flag searches (seen, unseen, …).
- SimpleImapQuery – easy one object query, where all conditions are joined with an AND operator.
- Expression syntax – most advanced, allows using AND and OR operators and sorting.
IMAP search is done entirely on the server side, which means that it’s fast and doesn’t require Mail.dll client to download much data over the network.
Installation
The easiest way to install Mail.dll IMAP client for .NET is to download it from nuget via Package Manager:
PM> Install-Package Mail.dll
Alternatively you can download Mail.dll directly from our website.
Connect to IMAP
Let’s start with the basics: we’ll connect to the IMAP server in .NET app and authenticate:
// C# code:
using (Imap imap = new Imap())
{
imap.ConnectSSL("imap.example.com");
imap.UseBestLogin("user", "password");
imap.SelectInbox();
// Search code goes here
imap.Close();
}
' VB.NET code:
Using imap As New Imap()
imap.ConnectSSL("imap.example.com")
imap.UseBestLogin("user", "password")
imap.SelectInbox()
' Search code here
imap.Close()
End Using
When using Gmail you can use application passwords, with Office 365 you’ll need to use OAuth 2.0 to authenticate.
Mail.dll fully supports OAuth 2.0 for authentication, you can find OAuth2 samples for Office365 and Gmail on the Mail.dll samples page.
Search(Flag)
Now, let’s look at the search code. The first and the simplest way to search is by using Imap.Search(Flag) method. This sample below finds all unseen email messages (those that have \UNSEEN flag).
// C#
List<long> uidList = imap.Search(Flag.Unseen);
// now download each message and get the subject
foreach (long uid in uidList)
{
IMail message = new MailBuilder()
.CreateFromEml(imap.GetMessageByUID(uid));
string subject = message.Subject;
}
' VB.NET
Dim uidList As List(Of Long) = imap.Search(Flag.Unseen)
' now download each message and get the subject
For Each uid As Long In uidList
Dim message As IMail = New MailBuilder()_
.CreateFromEml(imap.GetMessageByUID(uid))
Dim subject As String = message.Subject
Next
SimpleImapQuery
Second approach is to use an IMAP query object. The sample below searches for all unseen emails with a certain subject. All non-null SimpleImapQuery properties are combined using and operator.
// C#
SimpleImapQuery query = new SimpleImapQuery();
query.Subject = "subject to search";
query.Unseen = true;
List<long> uids = imap.Search(query);
' VB.NET
Dim query As New SimpleImapQuery()
query.Subject = "subject to search"
query.Unseen = True
Dim uids As List(Of Long) = imap.Search(query)
Expression syntax
Finally, the most advanced search option using Expression class. You can use AND, OR and NOT operators in your IMAP search.
Note that Mail.dll fully encapsulates IMAP search syntax, with easy to use and very readable .NET classes:
// C#
List<long> uids = imap.Search().Where(
Expression.And(
Expression.Not(Expression.Subject("subject not to search")),
Expression.HasFlag(Flag.Unseen)));
' VB.NET
Dim uids As List(Of Long) = imap.Search().Where(_
Expression.[And](_
Expression.[Not](Expression.Subject("subject not to search")),_
Expression.HasFlag(Flag.Unseen)))
Expression syntax with sorting
Expression search syntax also allows sorting (defined in RFC 5256).
This feature is not available for every IMAP server: you need to check if your IMAP server supports ImapExtension.Sort extension first.
// C#
List<long> uids = imap.Search()
.Where(Expression.And(
Expression.Not(Expression.Subject("subject not to search")),
Expression.HasFlag(Flag.Unseen)))
.Sort(SortBy.Multiple(
SortBy.Date(),
SortBy.Subject()));
' VB.NET
Dim uids As List(Of Long) = imap.Search() _
.Where(Expression.[And]( _
Expression.[Not](Expression.Subject("subject not to search")), _
Expression.HasFlag(Flag.Unseen))) _
.Sort(SortBy.Multiple( _
SortBy.[Date](), _
SortBy.Subject()))
)
Notice the neat trick in Mail.dll .NET client, that allows casting FluentSearch class, received from imap.Search() method, to List<longs>:
public static implicit operator List<long>(FluentSearch search)
{
return search.GetList();
}
We tend to use it very often for builder objects used in our unit tests.
Suggested reading
If you like it just give it a try and download it at: Mail.dll .NET IMAP component
Get Mail.dll