HOW TO: Build a complex search using SearchFilter and SearchFilterCollection in EWS Managed API 1.0

Here is another sample for building a complex search criteria for Finding items. We use the SearchFilter and SearchFilterCollection to build the “Restriction”. In short we are finding items which have a User Property called X-State AND the value of X-State is not (3 OR 4 OR 5) AND the ItemClass is IPM.Note.Exchange AND the mail is received after a certain date.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Exchange.WebServices.Data;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Xml;

namespace ListTopLevelFolders
class Program
static void Main(string[] args)
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);

//Change the Credentials to suit you needs
service.Credentials = new WebCredentials("akashb", "Password", "domain");

//Use Autodiscover or Set the URL manually. Change the email address to match yours



static void SearchItemsInAFolder(ExchangeService service)
// The User Property to Search
ExtendedPropertyDefinition X_STATE =
new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "X-STATE", MapiPropertyType.String);

// Condition for checking if X_STATE value is 3,4,5
List<SearchFilter> searchORFilterCollection = new List<SearchFilter>();
searchORFilterCollection.Add(new SearchFilter.IsEqualTo(X_STATE, 3));
searchORFilterCollection.Add(new SearchFilter.IsEqualTo(X_STATE, 4));
searchORFilterCollection.Add(new SearchFilter.IsEqualTo(X_STATE, 5));

//Negating the above condition. Effectively X_STATE value is NOT 3 OR 4 OR 5
SearchFilter searchNotFilter =
new SearchFilter.Not(new SearchFilter.SearchFilterCollection(LogicalOperator.Or, searchORFilterCollection.ToArray()));

// AND the ItemClass is IPM.Note.Exchange
// We create a new Search Filter collection and add a new IsEqualTo and then AND it with the
// previous search filter.
List<SearchFilter> searchANDFilterCollection = new List<SearchFilter>();
searchANDFilterCollection.Add(new SearchFilter.IsEqualTo(EmailMessageSchema.ItemClass, "IPM.Note.Exchange"));

// X_STATE is Not 3 OR 4 OR 5 AND ItemClass is IPM.Note.Exchange
SearchFilter searchANDFilter =
new SearchFilter.SearchFilterCollection(LogicalOperator.And, searchANDFilterCollection.ToArray());

// Condition for checking if X_STATE Exists in that Item
// AND the User Property Exists on the items.
// We create a new Search Filter collection and add a new Exists condition and then AND it with the
// previous search filter.
List<SearchFilter> searchANDFilterCollection2 = new List<SearchFilter>();
searchANDFilterCollection2.Add(new SearchFilter.Exists(X_STATE));

SearchFilter searchANDFilter2 = new SearchFilter.SearchFilterCollection(LogicalOperator.And, searchANDFilterCollection2.ToArray());

// Condition for checking if the mail has been recievd before a specific time.
// AND the mails have been received after a certain time.
// We create a new Search Filter collection and add a new IsGreaterThan condition and then AND it with the
// previous search filter.
List<SearchFilter> searchANDFilterCollection3 = new List<SearchFilter>();
searchANDFilterCollection3.Add(new SearchFilter.IsGreaterThan(EmailMessageSchema.DateTimeReceived, DateTime.Parse("2010-03-01T18:30:00Z")));

SearchFilter FinalsearchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, searchANDFilterCollection3.ToArray());

// Create a view with a page size of 50.
ItemView view = new ItemView(50);

// Indicate that the base property and the User Property will be returned
view.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties, X_STATE);

// Order the search results by the DateTimeReceived in descending order.
view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);

// Set the traversal to shallow. (Shallow is the default option; other options are Associated and SoftDeleted.)
view.Traversal = ItemTraversal.Shallow;

// Send the request to search the Inbox and get the results.
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, FinalsearchFilter, view);

// Process each item.
if (findResults.Items.Count > 0)
foreach (Item myItem in findResults.Items)
if (myItem is EmailMessage)
Console.WriteLine((myItem as EmailMessage).Subject);
if (myItem.ExtendedProperties.Count > 0)
// Display the extended property's name and property.
foreach (ExtendedProperty extendedProperty in myItem.ExtendedProperties)
Console.WriteLine(" Extended Property Name: " + extendedProperty.PropertyDefinition.Name);
Console.WriteLine(" Extended Property Value: " + extendedProperty.Value);

Console.WriteLine("No Items Found!");


Comments (2)

  1. Anonymous says:

    Hi akash

    Great article!!!!

    Can you please inform me how can we read mails from a particular user defined folder.

  2. akash says:

    You will have to do a FindFolder first to get the folder ID and then use the Folder ID in the FindItems call.