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
            service.AutodiscoverUrl("user@domain.com");
            
            SearchItemsInAFolder(service);
            
            Console.ReadLine();
        }

        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"));
            searchANDFilterCollection.Add(searchNotFilter);

            
            // 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));
            searchANDFilterCollection2.Add(searchANDFilter);

            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")));
            searchANDFilterCollection3.Add(searchANDFilter2);

            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);
                        }
                    }

                }
            }
            else
            {
                Console.WriteLine("No Items Found!");
            }

        }
    }
}

Enjoy!