Ted
Ted

Reputation: 2585

Enumberate and Filter Mail Folders using EWS Managed API

I'm trying to enumerate email only folders from an Exchange account using Microsoft.Exchange.WebServices Managed API and code based on this FindFolder() example.

The following code filters all empty folders, and Task, Search, Contacts and Calendar folders but still returns FreeBusy Data , Recoverable Items and Deletions folder.

Is there a way I can filter these from the folders returned other than by a string match on their name? And in fact, a way to filter Sent Items and Deleted Items too? (Although as these can't be renamed (and I've a better idea about what they are!), I'd be less worried about simply filtering these out by name)

Dim moreFoldersToReturn As Boolean = True
Const FOLDER_PAGE_SIZE As Integer = 10
Dim folderOffset As Integer = 0

While moreFoldersToReturn

    ' Create a view with a page size of x
    Dim view As New FolderView(FOLDER_PAGE_SIZE, folderOffset)

    ' Identify the properties to return in the results set.
    view.PropertySet = New PropertySet(BasePropertySet.IdOnly)
    view.PropertySet.Add(FolderSchema.DisplayName)

    ' Create an extended property definition for the PidTagAttributeHidden property.
    Dim isHiddenProp As ExtendedPropertyDefinition = New ExtendedPropertyDefinition(&H10F4, MapiPropertyType.Boolean)

    Dim searchFiltersCollection As List(Of SearchFilter) = New List(Of SearchFilter)
    searchFiltersCollection.Add(New SearchFilter.IsEqualTo(isHiddenProp, False)) 'filter hidden folders
    searchFiltersCollection.Add(New SearchFilter.IsGreaterThan(FolderSchema.TotalCount, 0)) 'filter empty folders

    Dim searchFilterToUse As SearchFilter = New SearchFilter.SearchFilterCollection(LogicalOperator.And, searchFiltersCollection.ToArray())

    ' Unlike FindItem searches, folder searches can be deep traversals.
    view.Traversal = FolderTraversal.Deep

    ' Send the request to search the mailbox and get the results.
    Dim results As FindFoldersResults = Me.exchangeServer.connection.FindFolders(WellKnownFolderName.Root, searchFilterToUse, view)


    ' Process each item.
    Dim folder As Folder
    For Each folder In results.Folders

        If Not TypeOf folder Is SearchFolder AndAlso
            Not TypeOf folder Is ContactsFolder AndAlso
            Not TypeOf folder Is TasksFolder AndAlso
            Not TypeOf folder Is CalendarFolder Then

            Debug.WriteLine("Folder: " & folder.DisplayName)
            foldersToReturn.Add(folder)

        End If

    Next

    folderOffset += FOLDER_PAGE_SIZE


    moreFoldersToReturn = results.MoreAvailable

End While

Gives the following output:

Folder: Freebusy Data
Folder: Recoverable Items
Folder: Deletions
Folder: Deleted Items
Folder: Inbox
Folder: Sent Items
Folder: TestEmailFolder

Upvotes: 2

Views: 1023

Answers (1)

Glen Scales
Glen Scales

Reputation: 22032

I would suggest you start your search from MsgFolderRoot rather then Root which means you won't get the Non_IPM Folders like recoverable Items, FreeBusy Data folder etc returned. You could also use a Search Folder and restrict the folder being returned to those that have a FolderClass of IPF.Note eg

SearchFilter sfFolder = new SearchFilter.IsEqualTo(FolderSchema.FolderClass,"IPF.Note");
FindFoldersResults  ffResults = service.FindFolders(WellKnownFolderName.MsgFolderRoot, sfFolder, new FolderView(1000));

But this may exclude some folders where no Folder Class has been set or that use a SubClass like IPF.Note.Microsoft.Conversation. So Filtering may still be the best option if you need to process these folders.

Upvotes: 6

Related Questions