Hunting those elusive Public Folders using Exchange Web Services (Part 2)

In the first of these posts, we created a binding to the Exchange Web Services (EWS) and managed to hunt down our public folder identity. But, as we left it, we're now stuck with just the identity and not anything else. Really, we want the items from inside a given folder, and to do that we need to use the 'FindItems' API call..

FindItems needs a FolderId and of course the our old friend - the ExchangeServiceBinding (see part 1 for how to create that!). Once again, in a familiar pattern, we need to create a request, then evaluate the response. So, onto the request...

In this case we'll be using a FindItemType request, we need to define the Traversal, ItemShape, ParentFolderIds and Item properties of the request. First, let's create a new item, and set its properties:

FindItemType request = new FindItemType();
request.Traversal = ItemQueryTraversalType.Shallow;

Shallow traversal again, though this isn't strictly needed here (I believe), we don't want to go into any sub-folders.

request.ItemShape = new ItemResponseShapeType();
request.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;

Here we've defined the shape of the item to be returned to us, by shape - what we mean is what the item will return to us, and in this case, we want all the properties.

request.ParentFolderIds = new FolderIdType[] { folder };

Finally, we set the parent folder id's, note, we can have more than one, though in our example case we'll only use one.
The last property to set (in this case, it's not a rule by any means) is the 'Item' property. We're going to use an IndexedPageViewType for our Item property.

IndexedPageViewType indexedPageView = new IndexedPageViewType();
indexedPageView.BasePoint = IndexBasePointType.Beginning;
indexedPageView.Offset = 0;
indexedPageView.MaxEntriesReturned = 100;
indexedPageView.MaxEntriesReturnedSpecified = true;

This allows us to implement paging, important if we're bringing back a lot of data, in this case, we've said we're starting at the beginning and only bringing back the first 100 (or all the items if there are less than that). Once we've created our indexedPageView, we can assign it to the Item property:

request.Item = indexedPageView;

Now all that is left is the actual call to the ExchangeServiceBinding.

FindItemResponseType response = esb.FindItem( request );

The next stage is to start interpretting the response. All responses from the EWS come as a specific type, generally <APICALL>ResponseType, and as far as I've seen so far, they contain a collection of <APICALL>ResponseMessageType in the 'ResponseMessages.Items' collection. So, that's where we begin -

foreach( FindItemResponseMessageType firmtMessage in response.ResponseMessages.Items)
{ /*...*/ }

It's important to check that the response indicates that the call has been successful or not, and to do that we check the 'ResponseClass' property of the message:

if(firmtMessage.ResponseClass == ResponseClassType.Success) { /*...*/ }

Of course the folder we've gone to may not even have any items in it, so we check that - and if it *does* have items? Well, we can start to read them....

if( firmtMessage.RootFolder.TotalItemsInView > 0 )
    foreach( ItemType item in ( (ArrayOfRealItemsType) firmtMessage.RootFolder.Item ).Items )
        Console.WriteLine( item.GetType().Name + ": " + item.Subject + ", " + item.DateTimeReceived.Date.ToString( "dd/MM/yyyy" ) );

Of course, this is just writing the basic information out to the screen, what about nifty things like reading the attachments etc?
Well - you might well think that this would be in this class, and much like me, you'd be wrong. Oh sure, it has a property called 'HasAttachments' which returns true if a Message has an attachment, and despite the fact that the message has a property called Attachments - the property will always be null. So, doing something like:

foreach(AttachmentType attachment in item.Attachments) { /*...*/ }

will *always* throw a NullReferenceException, grrrrrrr.... To get the attachments we'll need to venture into two other API calls - GetItem and GetAttachment, both of which I'll cover in my next post...

The full 'FindItems' method is below... In it's current form all it will do is list out the contents of a folder. It will work on any of the FolderIdType's you can give it, such as the Inbox, though I'm not so sure about the Calendar etc... I don't have access to the Exchange server at the moment so may give that a go in a day or so!

static void FindItems( ExchangeServiceBinding esb, FolderIdType folder )
{
    // Form the FindItem request
    FindItemType request = new FindItemType();
    request.Traversal = ItemQueryTraversalType.Shallow;
    request.ItemShape = new ItemResponseShapeType();
    request.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;
    request.ParentFolderIds = new FolderIdType[] { folder };
 
    IndexedPageViewType indexedPageView = new IndexedPageViewType();
    indexedPageView.BasePoint = IndexBasePointType.Beginning;
    indexedPageView.Offset = 0;
    indexedPageView.MaxEntriesReturned = 100;
    indexedPageView.MaxEntriesReturnedSpecified = true;
 
    request.Item = indexedPageView;
 
    FindItemResponseType response = esb.FindItem( request );
    foreach( FindItemResponseMessageType firmtMessage in response.ResponseMessages.Items )
    {
        if( firmtMessage.ResponseClass == ResponseClassType.Success )
        {
            if( firmtMessage.RootFolder.TotalItemsInView > 0 )
                foreach( ItemType item in ( (ArrayOfRealItemsType) firmtMessage.RootFolder.Item ).Items )
                    Console.WriteLine( item.GetType().Name + ": " + item.Subject + ", " + item.DateTimeReceived.Date.ToString( "dd/MM/yyyy" ) );
        }
        else
        {
            Console.WriteLine( "error: " + firmtMessage.MessageText );
        }
    }
}

Next time I'll go over the 'GetItems' and 'GetAttachment' API calls and save an attachment from an email to our temp directory.


[Edit: Part 3 is here]

Print | posted @ Friday, December 5, 2008 8:03 AM

Comments on this entry:

No comments posted yet.

Post A Comment
Title:
Name:
Email:
Comment:
Verification: