在 Exchange 2013 中使用 EWS 解决不明确的名称

了解如何使用 EWS 托管 API 或 EWS 通过从用户邮箱中的Active Directory 域服务 (AD DS) 或联系人文件夹获取可能的匹配项来解决不明确的名称。

组织中的用户会获得参加培训课程的员工的姓名和地址的手写列表。 他们希望向列表中的人员发送包含一些附加信息的电子邮件,但无法读取每个人的电子邮件地址。 如果要为应用程序中的用户解决此问题,EWS 可以提供帮助。 可以使用 ExchangeService.ResolveName EWS 托管 API 方法或 ResolveNames EWS 操作返回所选文本的潜在匹配项列表,例如姓氏的一部分。 返回的项目可以是公共用户邮箱、通讯组和联系人。

请注意,Exchange 将带有前缀路由类型(如 smtp 或 sip)的电子邮件地址保存在多值数组中。 在未解析名称的开头添加路由类型(如“sip:User1”)时, ResolveName 方法和 ResolveNames 操作对该数组的每个值执行部分匹配。 如果未指定路由类型,方法或操作将默认为 smtp,将其与主 smtp 地址属性匹配,而不搜索多值数组。 例如,如果搜索 User1 但不包含 sip 前缀,则不会收到 sip:User1@Contoso.com 结果,即使这是有效的邮箱也是如此。

只能在单个请求中指定一个不明确的名称。 如果有要解析的不明确名称列表,则需要循环访问该列表,并为每个条目调用 方法或操作。 用户的“联系人”文件夹中的考生将具有非空的项目 ID 值,然后可在 Contact.Bind 方法调用或 GetItem 操作请求中使用该值来检索其他信息。 如果候选项是通讯组,则可以使用 ExpandGroup (ItemId) EWS 托管 API 方法或 ExpandDL EWS 操作获取成员列表。 如果 returnContactDetails 参数或 ReturnFullContactData EWS 属性设置为 true,则通过 ResolveName 方法或 ResolveNames 操作返回的 Active Directory 条目将包含描述联系人的其他属性。 returnContactDetails 参数或 ReturnFullContactData 属性不会影响为联系人和联系人组返回的数据。

使用 EWS 托管 API 解决不明确的名称

可以使用 ResolveName 方法查找与传递的不明确名称匹配的候选项。 可以使用 ResolveName 方法的重载以五种不同的方式搜索候选项。

表 1. 重载 ResolveName 方法

方法 工作原理
ResolveName (String) 在用户的“联系人”文件夹和全局地址列表 (GAL) 中查找联系人 , 按此顺序。 字符串变量是尝试解析的不明确名称。
ResolveName (String、ResolveNameSearchLocation、Boolean) 在默认的“联系人”文件夹和/或“全局地址列表” (GAL) 中查找联系人。 字符串值是不明确的名称,搜索位置指定联系人文件夹和/或 GAL,布尔值指示是否返回完整的联系人信息。
ResolveName (String、ResolveNameSearchLocation、Boolean、PropertySet) 在默认的“联系人”文件夹和/或“全局地址列表” (GAL) 中查找联系人。 使用此方法可以设置返回的属性。
ResolveName (String、IEnumerable<FolderId>、ResolveNameSearchLocation、Boolean) 查找指定联系人文件夹中的联系人和/或全局地址列表 (GAL) 。 可以使用此方法传递要搜索的文件夹集合。 这使你可以查找默认的“联系人”文件夹以外的联系人文件夹。
ResolveName (String、IEnumerable<FolderId>、ResolveNameSearchLocation、Boolean、PropertySet) 查找全局地址列表 (GAL) 和/或特定联系人文件夹中的联系人。 使用此方法可以设置返回的属性。

让我们从一个简单的示例开始。 以下示例演示如何解析文本字符串“dan”并输出找到的每个候选项的名称和电子邮件地址。 此示例假定 service 是有效的 ExchangeService 对象,且用户已通过 Exchange 服务器的身份验证。

// Resolve the ambiguous name "dan".
   NameResolutionCollection resolvedNames = service.ResolveName("dan");
   // Output the list of candidates.
   foreach (NameResolution nameRes in resolvedNames)
   {
      Console.WriteLine("Contact name: " + nameRes.Mailbox.Name);
      Console.WriteLine("Contact e-mail address: " + nameRes.Mailbox.Address);
      Console.WriteLine("Mailbox type: " + nameRes.Mailbox.MailboxType);
   }

该响应最多返回 100 个候选项,但可能超过 100 个潜在候选项。 若要确定是否仅返回大量候选项的前 100 个候选项,请检查 NameResolutionCollection 对象中的 IncludesAllResolutions 的值。 如果值为 true,则不再有可能的候选项:如果值为 false,则该方法仅返回大量潜在候选项的前 100 个。

如果你在大型组织中工作,则像“dan”这样的名称可能会返回最多 100 名候选人。 若要减少返回的候选项数,请限制搜索位置。 下一个示例使用 ResolveNameSearchLocation 枚举指定搜索位置以解析不明确名称。

// Resolve the ambiguous name "dan".
// Only use the Contacts folder.
   NameResolutionCollection resolvedNames = service.ResolveName("dan", ResolveNameSearchLocation.ContactsOnly, false);
   // Output the list of candidates.   
   foreach (NameResolution nameRes in resolvedNames)
   {
      Console.WriteLine("Contact name: " + nameRes.Mailbox.Name);
      Console.WriteLine("Contact e-mail address: " + nameRes.Mailbox.Address);
      Console.WriteLine("Mailbox type: " + nameRes.Mailbox.MailboxType);
   }

如果将联系人存储在已知联系人文件夹以外的文件夹中,请使用其中一种重载的方法指定在何处查找候选项。 以下示例基于文件夹 ID 为 ResolveName 方法创建文件夹列表。 为了提高可读性, FolderId 已缩短。

// Create a list to store folders to search.
List<FolderId> folders = new List<FolderId>();
// Add a folder to the list based on the FolderId.
folders.Add(new FolderId("AABR8mboAAA="));
// Resolve the ambiguous name "dan".
// Only use the folders specified.
NameResolutionCollection resolvedNames = service.ResolveName("dan", folders, ResolveNameSearchLocation.ContactsOnly, false);
   foreach (NameResolution nameRes in resolvedNames)
   {
      Console.WriteLine("Contact name: " + nameRes.Mailbox.Name);
      Console.WriteLine("Contact e-mail address: " + nameRes.Mailbox.Address);
      Console.WriteLine("Mailbox type: " + nameRes.Mailbox.MailboxType);
   }

如果应用筛选器且未返回候选项, 则 NameResolutionCollection 将包含零个条目。 可以通过查看集合的 Count 属性来验证这一点。

使用 EWS 解决不明确的名称

可以使用 ResolveNames EWS 操作来识别不明确名称的可能候选项。 UnresolvedEntry 元素包含要解析的不明确名称。 以下示例演示如何解析名称 Sadie。 这也是 EWS 托管 API 在使用 ResolveName 方法时使用的 XML 请求,只是它为有效的输出示例使用不同的名称。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/"
               xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
  <soap:Body>
    <ResolveNames xmlns="https://schemas.microsoft.com/exchange/services/2006/messages"
                  xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
                  ReturnFullContactData="true">
      <UnresolvedEntry>Sadie</UnresolvedEntry>
    </ResolveNames>
  </soap:Body>
</soap:Envelope>

响应最多返回 100 个候选项,但可能超过 100 个候选项 若要确定是否只返回了大量候选项的前 100 个候选项,请检查 ResolutionSet 元素的 IncludesLastItemInRange 属性的值。 如果值为 true,则不再有可能的候选项:如果值为 false,则操作仅返回大量潜在候选项的前 100 个。

以下示例显示找到一个候选项时的 XML 响应。 请记住, ResolutionSet 最多可以包含 100 个候选项,每个候选项由 Resolution 元素及其子元素表示。

<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/" 
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <ResolveNamesResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" 
                          xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types" 
                          xmlns="https://schemas.microsoft.com/exchange/services/2006/messages">
      <m:ResponseMessages>
        <m:ResolveNamesResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
          <m:ResolutionSet TotalItemsInView="1" IncludesLastItemInRange="true">
            <t:Resolution>
              <t:Mailbox>
                <t:Name>Sadie Daniels</t:Name>
                <t:EmailAddress>Sadie@Contoso.com</t:EmailAddress>
                <t:RoutingType>SMTP</t:RoutingType>
                <t:MailboxType>Mailbox</t:MailboxType>
              </t:Mailbox>
              <t:Contact>
                <t:DisplayName>Sadie Daniels</t:DisplayName>
                <t:EmailAddresses>
                  <t:Entry Key="EmailAddress1">SMTP:Sadie@Contoso.com</t:Entry>
                </t:EmailAddresses>
                <t:ContactSource>ActiveDirectory</t:ContactSource>
              </t:Contact>
            </t:Resolution>
          </m:ResolutionSet>
        </m:ResolveNamesResponseMessage>
      </m:ResponseMessages>
    </ResolveNamesResponse>
  </soap:Body>
</soap:Envelope>

你并不总是想出你模棱两可的名字的候选人。 以下示例未找到候选项时,将 XML 响应显示为错误。

<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/" 
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <ResolveNamesResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" 
                          xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types" 
                          xmlns="https://schemas.microsoft.com/exchange/services/2006/messages">
      <m:ResponseMessages>
        <m:ResolveNamesResponseMessage ResponseClass="Error">
          <m:MessageText>No results were found.</m:MessageText>
          <m:ResponseCode>ErrorNameResolutionNoResults</m:ResponseCode>
          <m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
        </m:ResolveNamesResponseMessage>
      </m:ResponseMessages>
    </ResolveNamesResponse>
  </soap:Body>
</soap:Envelope>

另请参阅