views:

191

answers:

1

I need to write a method in C# that uses the Exchange Web Services (EWS) Managed API to read emails from a mailbox and given the ItemId/UniqueId of the current email, returns the ItemId/UniqueId of the next email in the inbox after the current email.

Furthermore, for various reasons I require the method to be a static stateless method, that is, it cannot rely on any member/global variables that persist between calls to the method. Thus I can't simply store a reference to an instance of a FindItemsResults object and move to the next Item each time the method is called.

I have tried implementing the method using the following code (simplified example only, no error checking):

using Microsoft.Exchange.WebServices;
using Microsoft.Exchange.WebServices.Data;
...
...
public string GetNextEmailId(string currentItemId)
{
    // set up Exchange Web Service connection
    ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
    service.AutodiscoverUrl("[email protected]");
    // create SearchFilter to find next email after current email
    ItemId itemId = new ItemId(currentItemId);
    SearchFilter sfNextEmail = new SearchFilter.IsGreaterThan(EmailMessageSchema.Id, itemId);
    // find next email in inbox
    ItemView itemView = new ItemView(1);
    itemView.OrderBy.Add(EmailMessageSchema.DateTimeReceived, SortDirection.Ascending);
    FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, sfNextEmail, itemView);
    // return unique ID of next email
    return findResults.Items[0].Id.UniqueId;
}

However when I run this method it throws the following exception from the service.FindItems line:

System.ArgumentException: "Validation failed. Parameter name: searchFilter"
Inner exception - Microsoft.Exchange.WebServices.Data.ServiceValidationException: "Values of type 'ItemId' cannot be as comparison values in search filters."

One option is to use FindItems to find all the emails in the Inbox and iterate through them checking the ItemId until I find the current email, then move to the next one and return its unique ID. But I think this is likely to be slow and inefficent. I am hoping there is a better way to achieve this.

Any help or suggestions would be greatly appreciated. I haven't been able to find any solutions searching the web.

+1  A: 

If you know the item id of the current email you can bind to it:

EmailMessage current = EmailMessage.Bind(service, id);

Then you have the current emails received date - create a search filter for all dates greater than that and the use your order by code you already have.

Chris