EWS从所有文件夹中获取未读电子邮件的数量

时间:2012-10-02 09:04:47

标签: c# winforms .net-3.5 exchangewebservices

我正在尝试从特定用户那里获取Exchange的未读电子邮件数量。

我可以从收件箱中获得大量电子邮件:

SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
ItemView view = new ItemView(int.MaxValue);
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, sf, view);
int unreadCount = 0;
foreach (EmailMessage i in findResults)
    {
        unreadCount++;
    }
label1.Text = unreadCount.ToString();

这很有用。
我也能够将所有子文件夹都收件箱:

FindFoldersResults findResults1 = service.FindFolders(
    WellKnownFolderName.Inbox,
    new FolderView(int.MaxValue) { Traversal = FolderTraversal.Deep });

foreach (Folder folder in findResults1.Folders)
{
    Console.WriteLine(folder.DisplayName);
}

问题是我无法将这两者结合在一起 我知道我可以做嵌套的foreach循环,但我想避免这种情况。

我发现了这些问题:Exchange Web Services (EWS) FindItems within All Folders,但它至少需要使用Outlook 2010才能创建AllItems文件夹。

我知道我可以创建SearchFilterCollection,但是如何添加规则以便它会在收件箱和所有子文件夹中搜索未读的电子邮件?

修改

这是我到目前为止所做的:

private int getEmailCount()
{
    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));

    FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, unreadFilter, viewEmails);
    unreadCount += findResults.Count();

    FindFoldersResults inboxFolders = service.FindFolders(WellKnownFolderName.Inbox, viewFolders);

    foreach (Folder folder in inboxFolders.Folders)
    {
        findResults = service.FindItems(folder.Id, unreadFilter, viewEmails);
        unreadCount += findResults.Count();
    }

    return unreadCount;
    }

基本上这可行,但是当我创建了多个子文件夹时,它开始工作得很慢 我可以使用一个查询而不是多个查询来获得相同的结果吗?

4 个答案:

答案 0 :(得分:4)

我搜索了一下并创建了这个功能:

    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);
    }

基本上它检查我们是否有AllItems文件夹可用 如果YES那么我们会做一个简单的查询,返回所有未读消息 如果NO,我们将所有文件夹循环到收件箱内。这个速度较慢,取决于我们有多少个文件夹和级别。

欢迎任何修复和改进:)

答案 1 :(得分:4)

不确定这是你在找什么,但...... 获取未读电子邮件(收件箱 / 草稿等):

int x = Folder.Bind(yourService, WellKnownFolderName.Inbox).UnreadCount;
int y = Folder.Bind(yourService, WellKnownFolderName.Drafts).UnreadCount;
return x + y;

在这种情况下,服务被调用两次,但调用是按顺序发出的 - 不够好

但是,您可以同时发出两个请求增加应用的响应时间

请参阅this或任何解释如何实例化两个 TPL 任务的教程,将它们发送到任务计划程序,< strong>等待两者( WaitAll())完成,最后检索他们的结果:)

并且,如果您想在应用一些自定义过滤器(而不是简单的“未读”过滤器)后获取电子邮件数量,请确保 ItemView 对象是 ItemView(1) ItemView(int.MaxValue)。然后,得到总数:

int n = findItemsResults.TotalCount;

请参阅docs for TotalCount property

这样,服务响应非常小 - 它只包含一个项目,但它(响应)也包含总计数...这就是你想要的,对吗?

答案 2 :(得分:1)

以下是获取邮箱未读总数的代码。

  1. 查找具有深度遍历的所有文件夹
  2. 将每个文件夹的属性集限制为id,unreadcount, displayname(forinformational)
  3. 日历,联系人等部分文件夹不具备此功能 财产如此处理案件
  4. 此代码段的限制:

    1. 如果邮箱在信息存储顶部包含超过1000个文件夹,则您将无法获得完整的未读总数
    2. 要处理这种情况,请在循环中执行finditems,直到没有更多具有相同逻辑的项目
    3. 这使得只有一个查找文件夹可以调用并处理结果。

      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;
      }
      

答案 3 :(得分:0)

获取文件夹及其计数的代码示例。在此示例中,我们列出了所有第一级文件夹,并将它们添加到公共类文件夹列表中,其中包含NewMessageCount对象。 Key是Folder.Bind(myService,folder.Id).UnreadCount部分。

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;
        }
    }