EWS托管Api中的电子邮件对话/电子邮件线程支持(针对Exchange 2010左右)

时间:2014-04-26 23:13:34

标签: asp.net exchange-server exchangewebservices ews-managed-api

EWS托管API 提供了一些用于检索和管理电子邮件会话的功能又名 电子邮件广告 )。不幸的是,其中很大一部分仅适用于新的版本的Exchange(2013等)。

Outlook确实对旧版版本的Exchange实施电子邮件线程。也许它通过自己管理线程来实现这一点(Outlook是桌面应用程序,电子邮件在本地计算机上复制,因此可以通过对话主题等轻松分组)。

现在,如何在 Web应用程序支持电子邮件线程?通常在Exchange客户端中支持此功能的操作是什么?通过支持我的意思是:

  • 检索前10个会话快照,然后检索接下来的10个会话快照 - 即支持分页(按需检索页面) - 此数据将用于构建主视图
  • 检索对话中的所有电子邮件 - 即按需检索对话的孩子) - 此数据将用于构建对话的详细信息视图

EWS Managed Api等问题:

  • EWS托管API中没有 Conversation.Bind(conversationId)
  • ExchangeService.FindItems(ConversationTopic的过滤器=="某些主题")绝不可靠(因为可能有不同的会话具有相同的主题)
  • ExchangeService.FindItems(对于ConversationId过滤==" QWERYUIO") - 我无法弄清楚如何使用这个:)是否有可能通过的conversationId ?
  • ExchangeService.GetConversationItems()等功能仅适用于以Exchange Online为目标的客户端和以Exchange Server 2013开头的Exchange版本。"

我现在使用的是什么(作为解决方法)

  1. 使用 ExchangeService.FindConversation()
  2. 检索(按需)一页对话页面
  3. 对于检索到的页面中的每个会话,请阅读 Conversation.GlobalIds 属性
  4. 通过连接所有会话的 Conversation.GlobalIds ,构建包含所有 GlobalIds 值的聚合(数组)
  5. 进行Exchange调用以将ID绑定到电子邮件( ExchangeService.BindToItems
  6. 执行电子邮件的 group-by 操作(从概念上讲,它是一个分组操作,但实现不是一个简单的逐个群组 - 电子邮件不能按 ConversationId分组,因为在使用Exchange 2010时该属性不可用,但文档未指定此内容)
  7. 使用数据一步构建UI 主视图的会话列表,详细信息视图的电子邮件组等等。
  8. 上述实施的一些问题

    • 我在调用 ExchangeService.BindToItems 操作时从服务器检索大量数据 - 性能不是很好,但也不是很糟糕。当然,仅当用户想要访问特定对话的详细信息视图时才检索电子邮件会更好。可能的hack:将GlobalIds数组保存在隐藏字段中的某个位置,然后使用它来获取电子邮件以构建详细信息视图。我知道GET请求的大小有限,但是......

    在电子邮件对话/电子邮件线程中,没有人知道哪些支持:

    • Here它表示 FindConversation(ViewBase,FolderId)适用于以Exchange Online为目标的客户端以及以Exchange Server 2013开头的Exchange版本。另一方面,here被写为ExchangeService.FindConversation()函数可用于从Exchange 2010开始的 Exchange版本,包括Exchange Online
    • This也很有趣:适用于:EWS托管API | Exchange Server 2010 Service Pack 1(SP1),但确保您拥有主要版本为15或更高版本的Exchange 2013或Exchange Online服务帐户。:)
    • Here它表示Item.ConversationId属性在从Exchange 2010开始的Exchange的版本中可用,包括Exchange Online。但它不是:)

    注意:我不太确定Item.ConversationId的支持,因为我手边没有代码,现在无法执行测试。因此,在使用针对Exchange 2010的EWS托管API时,如果该属性可用,请原谅我。

    总而言之, 您是否有任何想法在Web应用程序中使用针对Exchange 2010服务器的EWS托管API实现电子邮件对话/电子邮件线程功能?

    非常感谢您耐心阅读如此长篇文章:)

    一些参考文献:

    http://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.exchangeservice_methods%28v=exchg.80%29.aspx http://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.conversation_members%28v=exchg.80%29.aspx http://msdn.microsoft.com/en-us/library/office/gg274407%28v=exchg.80%29.aspx http://msdn.microsoft.com/en-us/library/office/jj220497%28v=exchg.80%29.aspx

    Implementing Outlook 2010's group by conversation using EWS and Exchange 2007 Exchange Webservice Managed API - Find items by extended properties

2 个答案:

答案 0 :(得分:5)

我已经解决了您在评论中提到的一些文档问题,因此我将尝试在此处回答您的实际编码问题。

要获取主视图,ExchangeService.FindConversation是正确的方法。它通过将结果限制为view参数指定的会话数来支持分页。您可以根据需要调用它来获取较旧和较旧的结果。

要获取详细视图,因为Exfor1010上没有ExchangeService.GetConversationItems,您可以将ExchangeService.FindItems与IsEqualTo SearchFilter一起使用,以搜索具有匹配ConversationId的项目(请参阅下面的代码)。这里有关于搜索过滤器的更多信息:How to: Use search filters with EWS in Exchange

在下面的方法中,我通过指定属性集来限制FindItems调用的属性,而不是返回所有属性。如果要返回所有属性,只需删除设置PropertySet的行。

static void forumFindConversationItem(ExchangeService service)
    {
        ItemView view = new ItemView(10);

        //Remove the following line if you want to get all the properties for each message. This will limit the properties returned in your results (and save time).
        view.PropertySet = new PropertySet(EmailMessageSchema.Subject, EmailMessageSchema.DateTimeReceived);

        SearchFilter.IsEqualTo conversationFilter =
            new SearchFilter.IsEqualTo(EmailMessageSchema.ConversationId, "AAQkADIwM2ZlM2ZlLWMwYjctNDg2Ny04MDU0LTVkMTFmM2IxY2ZjZQAQANEDR7V/30dphLiNOLSTuxE=");

        FindItemsResults<Item> results = service.FindItems(WellKnownFolderName.Inbox, conversationFilter, view);
    }

一旦你有了每个ItemID(由上面的代码返回),你可以使用Bind方法获得每个项目的所有属性。

希望有所帮助。当MSDN上的方法的版本控制问题得到更新时,我会跟进。

答案 1 :(得分:0)

更一般地说,ConversationID似乎存在一个问题,因为它在Exchange本身得到了普遍的理解和实际使用。这可能会影响您(或任何人)的发展。

我一直致力于制作电子邮件票务计划,并使用ConversationID将电子邮件聚集在一起,以便于查看。

但现在看来,有些电子邮件不在同一个帖子上 - 是的,它们共享相同的主题和发件人地址并且在相同的日期/时间发送 - 但它们不会在每个引用时发生其他(例如,一个电子邮件正文,以回应一个较旧的电子邮件主体是多少解释“电子邮件主题”) - 但这些不同的电子邮件具有相同的ConversationID,即使一个机构与另一个机构没有任何关系。

事实上,即使日期/时间不接近,例如,来自同一个人的“每日思想”电子邮件,这些电子邮件有时也会使用相同的ConversationID进行分组。在这种情况下,这可能听起来很有用,但在工资单人员发送“RE:401k”的商业案例中却没那么有用。

要清楚,这不是一个区分大小写的匹配,这是我之前使用Item.ExchangeID时的疏忽(如果您考虑案例,这是唯一的)。即使考虑到案例,完全不同的电子邮件线程也具有完全相同的ConversationID。

这表明我不能将ConversationID作为GROUP BY子句依赖,并且必须使用一些额外的自定义代码。