EWS searchFilter not working correctly with EWS FindItems call

I Am using a SearchFilter collection to restrict what emails are returned by a request to an Exchange 2010 mailbox using EWS.

I have no problem connecting to the service, and opening the mailbox.

The problem is that my searchFilter is being ignored, and all the emails are being returned by the request to EWS.

Here is my code:

static void Main(string[] args)
{
ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;

//creates an object that will represent the desired mailbox
Mailbox mb = new Mailbox(@"bbtest@bocuk.local");

// Find all items where the body contains "move reports".
//string qstring = "Body:\"move reports\"";

// Identify the item properties to return.
//view.PropertySet = new PropertySet(BasePropertySet.IdOnly,
//ItemSchema.Subject);

//creates a folder object that will point to inbox fold
FolderId fid = new FolderId(WellKnownFolderName.Inbox, mb);

//this will bind the mailbox you're looking for using your service instance
Folder inbox = Folder.Bind(service, fid);

List<SearchFilter> searchFilterCollection = new List<SearchFilter>();

searchFilterCollection.Add(new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false)));
searchFilterCollection.Add(new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.HasAttachments, true)));
searchFilterCollection.Add(new SearchFilter.Not(new SearchFilter.ContainsSubstring(ItemSchema.Subject, "FATS")));
searchFilterCollection.Add(new SearchFilter.Not(new SearchFilter.ContainsSubstring(ItemSchema.Subject, "Assignment")));
searchFilterCollection.Add(new SearchFilter.Not(new SearchFilter.ContainsSubstring(ItemSchema.Subject, "Sandbox: Assignment")));

SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.Or, searchFilterCollection.ToArray());

ItemView view = new ItemView(100);

string sAttachmentPath = "C:\\Dev\\EWSHelloWorld\\attachments\\";

// Find the first email message in the Inbox that has attachments. This results in a FindItem operation call to EWS.
FindItemsResults<Item> results = service.FindItems(WellKnownFolderName.Inbox, searchFilter, view);

foreach (EmailMessage email in results)
// looping through all the emails
{

System.Diagnostics.Debug.Write("Found attachemnt on msg with subject: " + email.Subject);

.... code removed for brevity!

So, according to my understanding of the searchFilter, only unread emails with attachments should be returned and they should not have FATS or Sandbox: Assignment as the subject.

But that's not working, the request to EWS just returnes all the emails.

What am I doing wrong please?

March 21st, 2014 9:32am

It would suggest when you doing this you enable tracing and then look at the restriction that is being sent to the server eg your searchfilter combination generates

        <m:Restriction>
          <t:Or>
            <t:IsEqualTo>
              <t:FieldURI FieldURI="message:IsRead" />
              <t:FieldURIOrConstant>
                <t:Constant Value="false" />
              </t:FieldURIOrConstant>
            </t:IsEqualTo>
            <t:IsEqualTo>
              <t:FieldURI FieldURI="item:HasAttachments" />
              <t:FieldURIOrConstant>
                <t:Constant Value="true" />
              </t:FieldURIOrConstant>
            </t:IsEqualTo>
            <t:Not>
              <t:Contains ContainmentMode="Substring" ContainmentComparison="IgnoreCase">
                <t:FieldURI FieldURI="item:Subject" />
                <t:Constant Value="FATS" />
              </t:Contains>
            </t:Not>
            <t:Not>
              <t:Contains ContainmentMode="Substring" ContainmentComparison="IgnoreCase">
                <t:FieldURI FieldURI="item:Subject" />
                <t:Constant Value="Assignment" />
              </t:Contains>
            </t:Not>
            <t:Not>
              <t:Contains ContainmentMode="Substring" ContainmentComparison="IgnoreCase">
                <t:FieldURI FieldURI="item:Subject" />
                <t:Constant Value="Sandbox: Assignment" />
              </t:Contains>
            </t:Not>
          </t:Or>
        </m:Restriction>

Where in your example you just need the collection of SearchFilter to be included under one AND grouping (eg IsUnread and HasAttachment and not subject1 and not subject2) so you need something like

            SearchFilter.SearchFilterCollection searchFilterCollection = new SearchFilter.SearchFilterCollection(LogicalOperator.And);
            searchFilterCollection.Add(new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
            searchFilterCollection.Add(new SearchFilter.IsEqualTo(EmailMessageSchema.HasAttachments, true));
            searchFilterCollection.Add(new SearchFilter.Not(new SearchFilter.ContainsSubstring(ItemSchema.Subject, "FATS")));
            searchFilterCollection.Add(new SearchFilter.Not(new SearchFilter.ContainsSubstring(ItemSchema.Subject, "Assignment")));
            searchFilterCollection.Add(new SearchFilter.Not(new SearchFilter.ContainsSubstring(ItemSchema.Subject, "Sandbox: Assignment")));

            ItemView view = new ItemView(100);

           // Find the first email message in the Inbox that has attachments. This results in a FindItem operation call to EWS.
            FindItemsResults<Item> results = service.FindItems(WellKnownFolderName.Inbox, searchFilterCollection, view);

My suggestion would be to avoid such complicated SearchFilters as when you try to apply these against folders with very large Item counts your gong to suffer a performance penalty and possibly search timeouts. If you just have a simple query on UnreadItems with Attachments that will always give good performance no matter what or how big the folder your running it against and then just filter out the false positives on the client side (given your only looking at unread with attachments these will be pretty few). Unless you have a real restiction on Bandwidth the complex query like your using is going to work against you. When you use SearchFilters it places a temporary restriction on the folder in question so you might want to take of read of http://technet.microsoft.com/en-us/library/cc535025%28EXCHG.80%29.aspx to understand the implication of overusing these. This is where using AQS is an advantage over using searchfilters

Cheers
Glen 

Free Windows Admin Tool Kit Click here and download it now
March 24th, 2014 12:38am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics