{"id":181,"date":"2023-07-31T15:49:47","date_gmt":"2023-07-31T13:49:47","guid":{"rendered":"http:\/\/www.limilabs.com\/blog\/?p=181"},"modified":"2023-08-11T11:03:03","modified_gmt":"2023-08-11T09:03:03","slug":"how-to-search-imap-in-net","status":"publish","type":"post","link":"https:\/\/www.limilabs.com\/blog\/how-to-search-imap-in-net","title":{"rendered":"How to search IMAP in .NET"},"content":{"rendered":"\n<p>One of many <a href=\"\/blog\/pop3-vs-imap\">advantages IMAP protocol has over POP3 protocol<\/a> is the ability to <strong>search<\/strong>. <\/p>\n\n\n\n<p>There are several ways of performing search using <a href=\"\/mail\">Mail.dll .NET IMAP library<\/a>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>Search(Flag)<\/em> &#8211; for common flag searches (seen, unseen, &#8230;).<\/li>\n\n\n\n<li><em>SimpleImapQuery<\/em> &#8211; easy one object query, where all conditions are joined with an AND operator.<\/li>\n\n\n\n<li><em>Expression <\/em>syntax &#8211; most advanced, allows using AND and OR operators and sorting.<\/li>\n<\/ul>\n\n\n\n<p>IMAP search is done <strong>entirely on the server side<\/strong>, which means that it&#8217;s fast and doesn&#8217;t require Mail.dll client to download much data over the network.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installation<\/h2>\n\n\n\n<p>The easiest way to install Mail.dll IMAP client for .NET is to download it from nuget via Package Manager:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\nPM&gt; Install-Package Mail.dll\n<\/pre><\/div>\n\n\n<p>Alternatively you can&nbsp;<a href=\"https:\/\/www.limilabs.com\/mail\/download\">download Mail.dll directly<\/a>&nbsp;from our website.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Connect to IMAP<\/h2>\n\n\n\n<p>Let&#8217;s start with the basics: we&#8217;ll connect to the IMAP server in .NET app and authenticate:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ C# code:\n\nusing (Imap imap = new Imap())\n{\n    imap.ConnectSSL(\"imap.example.com\");\n    imap.UseBestLogin(\"user\", \"password\");\n    imap.SelectInbox();\n\n    \/\/ Search code goes here\n\n    imap.Close();\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: vb; title: ; notranslate\" title=\"\">\n' VB.NET code:\n\nUsing imap As New Imap()\n    imap.ConnectSSL(\"imap.example.com\")\n    imap.UseBestLogin(\"user\", \"password\")\n    imap.SelectInbox()\n\n    ' Search code here\n\n    imap.Close()\nEnd Using\n<\/pre><\/div>\n\n\n<p>When using Gmail you can <a href=\"https:\/\/www.limilabs.com\/blog\/using-app-passwords-with-gmail\" title=\"Authenticate using Gmail\u2019s App Passwords to IMAP, POP3 and SMTP\">use application passwords<\/a>, with Office 365 you&#8217;ll need to use OAuth 2.0 to authenticate.<\/p>\n\n\n\n<p>Mail.dll fully supports&nbsp;<strong>OAuth 2.0&nbsp;<\/strong>for authentication, you can find&nbsp;<a href=\"https:\/\/www.limilabs.com\/mail\/samples\">OAuth2 samples for Office365 and Gmail on the Mail.dll samples<\/a>&nbsp;page.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Search(Flag)<\/h2>\n\n\n\n<p>Now, let&#8217;s look at the search code. The first and the simplest way to search is by using <em>Imap.Search(Flag)<\/em> method. This sample below finds all unseen email messages (those that have \\UNSEEN flag).<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ C#\n\nList&lt;long&gt; uidList = imap.Search(Flag.Unseen);\n\n\/\/ now download each message and get the subject\nforeach (long uid in uidList)\n{\n    IMail message = new MailBuilder()\n        .CreateFromEml(imap.GetMessageByUID(uid));\n\n    string subject = message.Subject;\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: vb; title: ; notranslate\" title=\"\">\n' VB.NET\n\nDim uidList As List(Of Long) = imap.Search(Flag.Unseen)\n\n' now download each message and get the subject\nFor Each uid As Long In uidList\n\tDim message As IMail = New MailBuilder()_\n\t\t.CreateFromEml(imap.GetMessageByUID(uid))\n\n\tDim subject As String = message.Subject\nNext\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">SimpleImapQuery<\/h2>\n\n\n\n<p>Second approach is to use an <strong>IMAP query object<\/strong>. The sample below searches for all unseen emails with a certain subject. All non-null <em>SimpleImapQuery <\/em>properties are combined using and operator.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ C#\n\nSimpleImapQuery query = new SimpleImapQuery();\nquery.Subject = &quot;subject to search&quot;;\nquery.Unseen = true;\n\nList&lt;long&gt; uids = imap.Search(query);\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: vb; title: ; notranslate\" title=\"\">\n' VB.NET\n\nDim query As New SimpleImapQuery()\nquery.Subject = \"subject to search\"\nquery.Unseen = True\n\nDim uids As List(Of Long) = imap.Search(query)\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Expression syntax<\/h2>\n\n\n\n<p>Finally, the most advanced search option using <em>Expression<\/em> class. You can use <strong>AND<\/strong>, <strong>OR<\/strong> and <strong>NOT<\/strong> operators in your IMAP search.<\/p>\n\n\n\n<p>Note that Mail.dll fully encapsulates IMAP search syntax, with easy to use and very readable .NET classes:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ C#\n\nList&lt;long&gt; uids = imap.Search().Where(\n    Expression.And(\n        Expression.Not(Expression.Subject(&quot;subject not to search&quot;)),\n        Expression.HasFlag(Flag.Unseen)));\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: vb; title: ; notranslate\" title=\"\">\n' VB.NET\n\nDim uids As List(Of Long) = imap.Search().Where(_\n    Expression.&#x5B;And](_\n        Expression.&#x5B;Not](Expression.Subject(\"subject not to search\")),_\n        Expression.HasFlag(Flag.Unseen)))\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Expression syntax with sorting<\/h2>\n\n\n\n<p>Expression search syntax also allows sorting (defined in <a href=\"\/mail\/rfc\/5256\">RFC 5256<\/a>). <\/p>\n\n\n\n<p>This feature is not available for every IMAP server: you need to check if your <a href=\"\/blog\/get-supported-server-extensions-imap-pop3-smtp\">IMAP server supports <em>ImapExtension.Sort<\/em> extension<\/a> first.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ C#\n\nList&lt;long&gt; uids = imap.Search()\n    .Where(Expression.And(\n            Expression.Not(Expression.Subject(&quot;subject not to search&quot;)),\n            Expression.HasFlag(Flag.Unseen)))\n    .Sort(SortBy.Multiple(\n            SortBy.Date(),\n            SortBy.Subject()));\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: vb; title: ; notranslate\" title=\"\">\n' VB.NET\n\nDim uids As List(Of Long) = imap.Search() _\n    .Where(Expression.&#x5B;And]( _\n        Expression.&#x5B;Not](Expression.Subject(\"subject not to search\")), _\n        Expression.HasFlag(Flag.Unseen))) _\n    .Sort(SortBy.Multiple( _\n        SortBy.&#x5B;Date](), _\n        SortBy.Subject()))\n)\n<\/pre><\/div>\n\n\n<p>Notice the neat trick in Mail.dll .NET client, that allows casting <em>FluentSearch<\/em> class, received from <em>imap.Search()<\/em> method, to <em>List&lt;longs&gt;<\/em>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic static implicit operator List&lt;long&gt;(FluentSearch search)\n{\n        return search.GetList();\n}\n<\/pre><\/div>\n\n\n<p>We tend to use it very often for builder objects used in our unit tests.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Suggested reading<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.limilabs.com\/blog\/receive-unseen-emails-using-imap\" title=\"Receive unseen emails using IMAP\">Receive unseen emails using IMAP<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.limilabs.com\/blog\/get-email-information-from-imap-fast\" title=\"Get email information from IMAP (fast)\">Get most common email fields for all messages fast<\/a><\/li>\n<\/ul>\n\n\n\n<p>If you like it just give it a try and download it at: <a href=\"\/mail\">Mail.dll .NET IMAP component<\/a><\/p>\n\n\n\n<br \/>\n<a class=\"btn btn-primary btn-largest btn-action\" href=\"\/mail\/download\">Get Mail.dll<\/a>\n<br \/>\n\n","protected":false},"excerpt":{"rendered":"<p>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: IMAP search is done entirely on the server side, which means that it&#8217;s fast and doesn&#8217;t require Mail.dll client to download much data over the network. Installation The [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[15,28,77,57],"class_list":["post-181","post","type-post","status-publish","format-standard","hentry","category-mail-dll","tag-c","tag-imap","tag-imap-component","tag-vb-net"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/181"}],"collection":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/comments?post=181"}],"version-history":[{"count":16,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/181\/revisions"}],"predecessor-version":[{"id":6538,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/181\/revisions\/6538"}],"wp:attachment":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/media?parent=181"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/categories?post=181"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/tags?post=181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}