EWS触发OnNotificationEvent修改事件时如何获取变更字段及历史版本
问题1:查询修改事件具体变更的字段
EWS的流式通知本身不会直接返回本次变更的字段差异,你可以通过两种方案实现该需求:
- 本地缓存对比方案:
你需要在本地持久化存储每个日历项的基准状态,包括ItemId、ChangeKey以及你需要监控的所有目标字段值。当接收到Modified类型的通知时,调用Appointment.Bind()拉取当前最新的日历项属性,和本地缓存的上一版本状态逐字段对比,即可得到所有发生变更的字段列表。
参考代码:// 拉取本次修改后的最新日历项数据 Appointment newVersion = Appointment.Bind(ewsService, notification.ItemId, new PropertySet(BasePropertySet.FirstClassProperties)); // 与本地缓存的oldVersion逐字段对比 if (newVersion.Subject != oldVersion.Subject) { // 记录主题字段发生变更 } if (newVersion.Start != oldVersion.Start || newVersion.End != oldVersion.End) { // 记录时间字段发生变更 } - 扩展属性辅助方案:
你可以在拉取日历项时加载扩展属性PR_ChangeKeyHistory(属性标记为0x65E30102),该属性会存储该条目所有历史ChangeKey的有序列表,搭配历史版本查询功能可实现跨版本的字段差异对比。
问题2:获取日历项修改前的历史版本
EWS原生支持查询项目的历史版本,具体操作步骤如下:
- 调用
ExchangeService.GetItemVersions()方法,传入目标日历项的ItemId,即可得到该条目所有历史版本的ID集合,每个版本对应唯一的ItemId和ChangeKey - 对返回的版本列表按时间排序,默认返回结果中最新版本排在第一位,取第二位即为本次修改前的历史版本,调用Bind方法即可加载该版本的完整属性值。
参考代码:
// 获取该日历项的所有历史版本列表 var itemVersions = ewsService.GetItemVersions(targetItemId, new PropertySet(BasePropertySet.IdOnly)); // 跳过当前最新版本,取上一个版本即为修改前的版本 var oldVersionId = itemVersions.Skip(1).FirstOrDefault()?.Id; if (oldVersionId != null) { Appointment oldVersion = Appointment.Bind(ewsService, oldVersionId, new PropertySet(BasePropertySet.FirstClassProperties)); // 处理旧版本数据 }
注意:历史版本的保留时长由Exchange服务器的保留策略配置决定,默认保留时长为14天,超出保留时间的历史版本会被服务器自动清理,无法查询。
内容的提问来源于stack exchange,提问作者Øyvind Kleppe
相关产品推荐
相关产品推荐

