I\'m trying to get number of unread emails from Exchange for specific user.
I\'m able to get number of emails from Inbox like so:
SearchFilter sf = n
Not sure it's what you were looking for, but... Getting unread emails counts (inbox / draft etc.):
int x = Folder.Bind(yourService, WellKnownFolderName.Inbox).UnreadCount;
int y = Folder.Bind(yourService, WellKnownFolderName.Drafts).UnreadCount;
return x + y;
In this case, the service is called two times, but the calls are issued sequentially - not good enough.
Though, you can issue both requests at the same time and increase the response time of your app.
See this or any tutorial that explains how to instantiate two TPL tasks, send them to the task scheduler, wait for both (WaitAll()) to complete and, in the end, retrieve their results :)
And, if you want to get the email counts after applying some custom filters (not the trivial 'unread' filter), then make sure that your ItemView object is ItemView(1), not ItemView(int.MaxValue). Then, get the total count:
int n = findItemsResults.TotalCount;
See the docs for TotalCount property.
This way, the service response is quite small - it contains only one item, but it (the response) also carries the total count... That's what you want, right?
Here is the code for fetching the total unread count of a mailbox.
Limitations with this code snippet:
This makes only one findfolders call and work on the results.
public static int GetTotalUnreadCount(ExchangeService ewsConnector)
{
int pagedView = 1000;
FolderView fv = new FolderView(pagedView) { Traversal = Microsoft.Exchange.WebServices.Data.FolderTraversal.Deep };
fv.PropertySet = new PropertySet(BasePropertySet.IdOnly, FolderSchema.UnreadCount, FolderSchema.DisplayName);
FindFoldersResults findResults = ewsConnector.FindFolders(WellKnownFolderName.MsgFolderRoot, fv);
int totalUnreadCount = 0;
foreach (Folder f in findResults.Folders)
{
try
{
totalUnreadCount += f.UnreadCount;
Console.WriteLine("Folder [" + f.DisplayName + "] has [" + f.UnreadCount.ToString() + "] unread items.");
}
catch(Exception ex)
{
Console.WriteLine("Folder [" + f.DisplayName + "] does not have the unread property.");
}
}
Console.WriteLine("Mailbox has [" + totalUnreadCount.ToString() + "] unread items.");
return totalUnreadCount;
}
I've searched a bit and created this function:
public void getEmailCount(Action<int> callback)
{
int unreadCount = 0;
FolderView viewFolders = new FolderView(int.MaxValue) { Traversal = FolderTraversal.Deep, PropertySet = new PropertySet(BasePropertySet.IdOnly) };
ItemView viewEmails = new ItemView(int.MaxValue) { PropertySet = new PropertySet(BasePropertySet.IdOnly) };
SearchFilter unreadFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
SearchFilter folderFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "AllItems"));
FindFoldersResults inboxFolders = service.FindFolders(WellKnownFolderName.Root, folderFilter, viewFolders);
if (inboxFolders.Count() == 0)//if we don't have AllItems folder
{
//search all items in Inbox and subfolders
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, unreadFilter, viewEmails);
unreadCount += findResults.Count();
inboxFolders = service.FindFolders(WellKnownFolderName.Inbox, viewFolders);
foreach (Folder folder in inboxFolders.Folders)
{
findResults = service.FindItems(folder.Id, unreadFilter, viewEmails);
unreadCount += findResults.Count();
}
}
else //AllItems is avilable
{
foreach (Folder folder in inboxFolders.Folders)
{
FindItemsResults<Item> findResults = service.FindItems(folder.Id, unreadFilter, viewEmails);
unreadCount += findResults.Count();
}
}
callback(unreadCount);
}
Basically it checks if we have AllItems folder avilable.
If YES then we do one, simple query that returns all unread messages.
If NO then we loop all folders inside Inbox. This is slower and depends on how many folders and levels we have.
Any fixes and improvements are welcome :)
Code example for fetching folders and their counts. In this example, we are listing all first-level folders, and adding them to a common class list of folders, with a NewMessageCount object in there. Key is the Folder.Bind(myService, folder.Id).UnreadCount section.
public List<Common.MailFolder> ListFolders()
{
try
{
List<Common.MailFolder> myFolders = new List<Common.MailFolder>();
Common.MailFolder myFolder;
List<ExchangeFolder> myExchangeFolders = new List<ExchangeFolder>();
FolderView myView = new FolderView(10);
myView.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties, FolderSchema.DisplayName, FolderSchema.Id);
myView.Traversal = FolderTraversal.Shallow;
FindFoldersResults myResults = myService.FindFolders(WellKnownFolderName.MsgFolderRoot, myView);
foreach (Folder folder in myResults)
{
myFolder = new Common.ICE.MailFolder();
myFolder.NewMessageCount = Folder.Bind(myService, folder.Id).UnreadCount;
myFolder.FolderId = folder.Id.ToString();
myFolder.FolderName = folder.DisplayName;
myFolders.Add(myFolder);
}
return myFolders;
}
catch (Exception ex)
{
Logger.Log.Error("Exchange Helper - List Folders", ex, Utility.GetUserId());
return null;
}
}