5

我正在尝试从 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 inside 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

4 回答 4

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然后我们循环收件箱中的所有文件夹。这比较慢,取决于我们有多少文件夹和级别。

欢迎任何修复和改进:)

于 2012-10-02T13:53:45.503 回答
4

不确定这是您要查找的内容,但是...获取未读电子邮件很重要(收件箱/草稿等):

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

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

不过,您可以同时发出两个请求并增加应用程序的响应时间。

请参阅教程或任何解释如何实例化两个TPL 任务、将它们发送到任务调度程序等待两者(WaitAll())完成并最终检索它们的结果的教程:)

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

int n = findItemsResults.TotalCount;

请参阅TotalCount 属性的文档。

这样,服务响应就很小了——它只包含一个项目,但它(响应)也带有总数……这就是你想要的,对吧?

于 2014-01-18T10:43:33.163 回答
1

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

  1. 查找所有深度遍历的文件夹
  2. 将每个文件夹的属性集限制为 id、未读计数、显示名称(仅供参考)
  3. 某些文件夹(如日历、联系人)没有此属性,因此请处理这种情况

此代码段的限制:

  1. 如果邮箱在 Top of information store 下包含超过 1000 个文件夹,那么您将无法获得完整的未读总数
  2. 要处理这种情况,请在循环中执行 finditems,直到没有更多具有相同逻辑的项目

这使得只有一个 findfolders 调用并处理结果。

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;
}
于 2015-06-03T16:03:17.403 回答
0

获取文件夹及其计数的代码示例。在此示例中,我们列出了所有第一级文件夹,并将它们添加到文件夹的公共类列表中,其中包含一个 NewMessageCount 对象。关键是 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;
        }
    }
于 2015-01-14T19:36:28.237 回答