我正在尝试从特定用户那里获取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;
}
基本上这可行,但是当我创建了多个子文件夹时,它开始工作得很慢 我可以使用一个查询而不是多个查询来获得相同的结果吗?
答案 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)
以下是获取邮箱未读总数的代码。
此代码段的限制:
这使得只有一个查找文件夹可以调用并处理结果。
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;
}
}