EWS 中的复制操作和扩展属性的问题

Posted

技术标签:

【中文标题】EWS 中的复制操作和扩展属性的问题【英文标题】:Woes with copy operation and extended properties in EWS 【发布时间】:2018-11-23 17:22:17 【问题描述】:

我的任务是通过一项服务双向同步两个邮箱中的联系人文件夹。 请多多包涵,因为这是我第一次在 C# 中使用 EWS。

为了唯一标识项目并跟踪同步更改,我将SyncFolderHierarchy() 用于子文件夹,SyncFolderItems() 用于每个子文件夹中的项目,同时跟踪同步状态。

由于文件夹/项目 ID 依赖于邮箱、初始同步以及创建操作,我通过 Item.SetExtendedProperty() 使用扩展属性标记同步项目

这确实很好,但我遇到了一个警告。

当用户在 Outlook 中复制和粘贴文件夹或联系人时,它还会复制唯一 ID(扩展属性),使其不再唯一。 在这种情况下,我现在在一个邮箱中有两个具有相同“唯一”ID 的项目,并且现在该项目有一个模棱两可的匹配项。

基本上:

    SyncFolderItems() 被调用,同步状态被保存 如果项目没有唯一 ID,则使用唯一 ID 进行标记 用户复制并粘贴项目 SyncFolderItems() 被调用(与之前的同步状态),为用户复制的项目返回一个 Create 事件 创建的项目已有唯一 ID

现在,有人可能会争辩说只是在创建事件中覆盖项目的唯一 ID。

但是,这会导致以下问题:

当我将邮箱 A 中的新项目同步到邮箱 B 时,我还创建了一个项目。 现在调用邮箱 A 上的 SyncFolderItems() 后,我还会为我自己的项目检索一个 Create 事件,在这种情况下,它已经合法地分配了一个不能被覆盖的唯一 ID。

我基本上看到了两种选择:

以某种方式阻止此扩展属性可复制

防止 EWS 为我自己创建的项目发送创建。 我知道我可以在 SyncFolderItems() 调用中忽略 ItemID,但我不确定我应该如何跟踪调用中的项目 ID,因为它们可能会根据 documentation 发生变化

是否有人对如何以不同方式处理此问题或实施任一选项有任何建议?

【问题讨论】:

两个数据库之间的直接同步要求密钥实际上是唯一的。正如你所说,他们没有正确地做到这一点。所以你需要一个第三个数据库。某些文件格式或其他您和您提供主键的文件格式。这样您就可以控制并保持每个键实际上是唯一的。 是的,我正在考虑在 sqlite 中进行跟踪。但是,在复制时,Exchange 仍会复制我分配给项目的唯一键,或者在数据库术语中,违反了该约束。因此,将密钥保留在第三位仍然会导致匹配不明确:/ @Christopher 澄清一下:您的意思是保留所有发布过的同步 ID,并且当更改事件带有从未见过的同步 ID 时,忽略它?我目前正在考虑注意事项,可能会尝试一下...... 我的意思是忽略 Exchange 中的密钥。它不可靠,而且可能永远不会。您甚至可能会误用一个并非用于主键的字段。有第三个数据库。让 it 成为两个端点状态的权威。 @Christopher 是的,好的,所以让我问一下:似乎不能保证 ItemID/FolderID 保持不变。因此,如果我将其存储在主数据库中,如何在SyncFolderItems() 调用中将项目与主数据库匹配? docs.microsoft.com/en-us/previous-versions/office/developer/… 的代码示例仅提及“Todo: Update / Delete / ... item on client”和ic.ItemId.UniqueId:这里的 ItemID(或 uniqueID)是否保证与之前看到的内容匹配? 【参考方案1】:

Exchange id 也应该是你的唯一的 id。将您的 id 保留在项目本身上确实不值得 - 首先,这需要修改该项目(即使是您导致更改也会产生更改事件),其次,因为您已经请注意,您最终可能会得到相同项目的重复或三次重复。

约会更糟糕 - 每个传入的约会更新都会导致 Outlook 重新创建约会,从而导致使用新的 id 并清除您的自定义属性。

【讨论】:

感谢您的意见,德米特里。我只是对使用它持谨慎态度,因为docs.microsoft.com/en-us/exchange/client-developer/… 声明Don't assume that your ID will always be valid if you need to retrieve the item at a later time。当然,我宁愿使用这个 ID,也不愿摆弄自定义属性!所以你说 ChangeState 中的 ID 会是以前见过的东西? 只要物品在那里,您应该可以使用它。如果没有,您可以假设该项目已被删除/重新创建/移动到不同的邮箱/等。 谢谢。我目前正在实施,如果可行,我将在下周报告/接受! 在数据库中将双方的 ItemIds 和 FolderIds 相互映射当然很乏味,但似乎效果很好。

以上是关于EWS 中的复制操作和扩展属性的问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 EWS 列出所有可用的扩展属性

使用扩展属性字段 (EWS) 在 EmailMessage 中创建投票

预警系统 | Powershell:加载日历项扩展属性

在 TypeScript 中使用解构/扩展复制具有重命名属性的对象

配置gradle :将properties文件转换为扩展属性

配置gradle :将properties文件转换为扩展属性