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

問題は、これら 2 つを組み合わせることができないことです。
ネストされた 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;
    }

基本的にこれは機能しますが、複数のサブフォルダーを作成すると、動作が非常に遅くなりました。
複数のクエリの代わりに、同じ結果を得るために 1 つのクエリを実行できますか?

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フォルダが利用可能かどうかをチェックします。次に、すべての未読メッセージを返す1つの単純なクエリを実行します
。 その場合、受信トレイ内のすべてのフォルダーをループします。これは遅く、フォルダとレベルの数によって異なります。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;

この場合、サービスは 2 回呼び出されますが、呼び出しは順番に発行されます。十分ではありません

ただし、両方のリクエストを同時に発行して、アプリの応答時間を長くすることはできます。

thisまたは 2 つのTPL タスクをインスタンス化し、それらをタスク スケジューラに送信し、両方 ( WaitAll() ) が完了するのを待ち、最後にそれらの結果を取得する方法を説明するチュートリアルを参照してください:)

また、いくつかのカスタム フィルター (単純な「未読」フィルターではなく) を適用した後にメール数を取得する場合は、ItemViewオブジェクトがItemView( int.MaxValue )ではなくItemView (1)であることを確認してください。次に、合計数を取得します。

int n = findItemsResults.TotalCount;

TotalCount プロパティのドキュメントを参照してください。

このように、サービス レスポンスは非常に小さくなります。1 つのアイテムしか含まれていませんが、それ (レスポンス) には合計カウントも含まれています。

于 2014-01-18T10:43:33.163 に答える
1

メールボックスの合計未読数を取得するためのコードを次に示します。

  1. 深いトラバーサルですべてのフォルダーを見つける
  2. 各フォルダの一連のプロパティを id、unreadcount、displayname に制限します (情報提供目的)。
  3. カレンダー、連絡先などの一部のフォルダーにはこのプロパティがないため、そのケースを処理します

このコード スニペットの制限:

  1. メールボックスのトップ オブ インフォメーション ストアの下に 1000 を超えるフォルダが含まれている場合、未読の合計数を完全に取得することはできません。
  2. そのケースを処理するには、同じロジックを持つアイテムがなくなるまでループ内で finditems を実行します

これにより、findfolders が 1 つだけ呼び出され、結果が処理されます。

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 に答える