基于EWS FindPeople实现Exchange 2013/2016 GAL与本地联系人聚合查询
实现Exchange GAL与本地联系人的聚合姓名查询(兼容2013/2016)
刚好我之前做过类似需求,Exchange 2013及后续版本的EWS API里的FindPeople方法完全能搞定这个场景——不用折腾多个接口,统一用它就能实现全局地址列表(GAL)和用户本地联系人的聚合查询,还能返回联系电话这类详情。
下面是关键实现要点和示例:
- 核心API选型:
FindPeople是Exchange 2013开始引入的接口,原生支持查询GAL和用户本地联系人文件夹,完美适配你的跨版本需求(2013和2016版本行为一致,无需做版本分支处理)。 - 姓名筛选器配置:针对
GivenName和Surname字段构造搜索过滤器,可以用模糊匹配(ContainsSubstring)或者精确匹配(Equals),根据业务需求调整。 - 结果聚合与去重:分别查询GAL和本地联系人后,合并结果并做去重处理(比如通过邮箱地址判断重复条目),避免返回重复的联系人信息。
- 返回字段控制:默认
FindPeople会返回基础属性,如果需要更多详情(如联系电话),可以通过PropertySet指定需要加载的属性,减少冗余数据传输。
示例代码(C#)
// 初始化EWS服务实例,兼容Exchange 2013/2016 ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013_SP1); service.Credentials = new WebCredentials("your-username", "your-password"); service.Url = new Uri("https://your-exchange-server/EWS/Exchange.asmx"); // 构造姓名筛选条件:匹配GivenName和Surname包含指定关键词 var nameFilter = new SearchFilter.SearchFilterCollection( LogicalOperator.And, new SearchFilter.ContainsSubstring(ContactSchema.GivenName, "John"), new SearchFilter.ContainsSubstring(ContactSchema.Surname, "Doe") ); // 定义需要返回的属性(包含联系电话) PropertySet contactProps = new PropertySet(BasePropertySet.FirstClassProperties) { ContactSchema.GivenName, ContactSchema.Surname, ContactSchema.PhoneNumbers, ContactSchema.EmailAddresses }; // 查询全局地址列表(GAL) var galResults = service.FindPeople( WellKnownFolderName.GlobalAddressList, nameFilter, new ItemView(100) ); galResults.People.LoadPropertiesForItems(contactProps); // 查询用户本地联系人 var localResults = service.FindPeople( WellKnownFolderName.Contacts, nameFilter, new ItemView(100) ); localResults.People.LoadPropertiesForItems(contactProps); // 聚合结果并去重(按主邮箱地址分组,无邮箱则用唯一ID) var aggregatedContacts = galResults.People.Concat(localResults.People) .GroupBy(p => p.EmailAddresses.TryGetValue(EmailAddressKey.EmailAddress1, out var addr) ? addr.Address : p.Id.UniqueId) .Select(g => g.First()) .ToList(); // 遍历输出联系人详情 foreach (var contact in aggregatedContacts) { Console.WriteLine($"姓名: {contact.GivenName} {contact.Surname}"); Console.WriteLine("联系电话:"); foreach (var phoneEntry in contact.PhoneNumbers) { Console.WriteLine($"- {phoneEntry.Key}: {phoneEntry.Value}"); } Console.WriteLine("---"); }
注意事项
- 确保Exchange服务的EWS端点配置正确,并且账号拥有访问GAL和本地联系人的权限。
- 如果需要分页查询大量结果,可以调整
ItemView的分页大小,并通过FindPeopleResults.MoreAvailable判断是否需要继续获取下一页数据。
内容的提问来源于stack exchange,提问作者Maxim
相关产品推荐
相关产品推荐

