检索 Outlook 建议的联系人

Retrieve suggested contacts of Outlook

我的公司在 Office 365 下。 我的目标是在我的 asp .net MVC 应用程序中检索 Outlook 建议的用户联系人(自动完成列表中显示的联系人)。 该网站配置为使用 Windows 身份验证自动登录,我不想询问用户他的凭据。

我必须尝试使用​​ Exchange Web 服务检索建议的联系人,但使用此代码只能成功检索 "real" 个联系人:

public List<Contact> GetContacts()
{
  ContactsFolder.Bind(this._service, WellKnownFolderName.Contacts);
  ItemView itemView = new ItemView(1000);
  itemView.PropertySet = new PropertySet(BasePropertySet.IdOnly, new PropertyDefinitionBase[4]
  {
    (PropertyDefinitionBase) ContactSchema.DisplayName,
    (PropertyDefinitionBase) ContactSchema.Surname,
    (PropertyDefinitionBase) ContactSchema.GivenName,
    (PropertyDefinitionBase) ContactSchema.EmailAddress1
  });
  FindItemsResults<Item> items = this._service.FindItems(WellKnownFolderName.Contacts, (ViewBase) itemView);
  List<Contact> list = new List<Contact>();
  foreach (Item obj in items)
  {
    if (obj is Contact)
      list.Add(obj as Contact);
  }
  return list;
}

然后,我尝试使用 People Api of Office 365 REST API but I don't know how to make the call without asking for the user login/password. This is a sample of a try (if I don't use the proxy, I receive an HTTP 407 Error) :

    public async Task Try()
    {
        var proxy = WebRequest.GetSystemWebProxy();
        proxy.Credentials = new NetworkCredential("foo", "1234");


        // Now create a client handler which uses that proxy
        HttpClient client = null;
        HttpClientHandler httpClientHandler = new HttpClientHandler()
        {
            Proxy = proxy,
            PreAuthenticate = true,
            UseDefaultCredentials = false,
            Credentials = new NetworkCredential("foo@foo.com", "1234")
        };
        var httpClient = new HttpClient(httpClientHandler);
        var result = await httpClient.GetAsync("https://outlook.office.com/api/beta/me/people");

        var stringContent = await result.Content.ReadAsStringAsync();
    }

关于建议的联系人问题

我在想你没有在正确的文件夹中查找。根据我通过谷歌搜索所见,建议的联系人不在 Contacts 目录中,而是在 Suggested Contacts 中。在您的 EWS 示例中,您正在查找联系人... 请参阅 this discussion. Look also at this guy post,他设法使用 EWS 和 powershell 访问建议的联系人文件夹,因此毫无疑问这对于 C# 和 EWS .NET SDK 是可行的。我的建议是继续尝试您的示例 1。

关于身份验证问题

我要强调的是,您的请求应该被授权访问 Exchange Web 服务(代码示例 1)或 outlook REST API(代码示例 2)。

在示例 1 中,我们看不到 _service 字段是如何实例化的,但我敢打赌,有一段代码看起来或多或少类似于下面的行,因此您可以请求 EWS。

ExchangeService service = new ExchangeService();
service.Credentials = new OAuthCredentials(token);
service.Url = new Uri(ewsUrl);

token 大概可以重用于 Outlook REST API, 尝试在 httpClient

中的 bearer 中设置它

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "Your Oauth token");

现在您的请求应该已获得授权,但您仍然遇到代理问题。我敢打赌,这只会在您的组织内发生,因为您的 IT 设置了代理。您可能不会在生产中需要它。您可以在本地开发时使用调试语句使其工作。

 #if DEBUG
 IWebProxy webProxy = System.Net.WebRequest.DefaultWebProxy;
 if (webProxy!=null && !webProxy.IsBypassed(new Uri(endpoint)))
  {
      client.Proxy = webProxy;
  }
 #endif

我从未找到 post 的 "Suggested Contacts" 文件夹。 我最后使用了似乎可以完成这项工作的文件夹 "AllContacts"。

    public List<Contact> GetSuggestedContacts()
    {
        // Instantiate the item view with the number of items to retrieve from the Contacts folder.
        ItemView view = new ItemView(1000);

        // To keep the request smaller, request only the display name property.
        view.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties, ContactSchema.DisplayName, ContactSchema.Surname, ContactSchema.GivenName, ContactSchema.EmailAddress1);

        // Retrieve the RecipientCache folder in the Contacts folder that have the properties that you selected.
        var contactFolders = _service.FindFolders(new FolderId(WellKnownFolderName.Root), new FolderView(500));
        var folder = contactFolders.Folders.SingleOrDefault(x => x.DisplayName == "AllContacts");

        if(folder == null) return new List<Contact>();

        //Cast Item in Contact and filtered only real adresses
        var cacheContacts = folder.FindItems(view).Items.OfType<Contact>().Where(x => x.EmailAddresses.Contains(0) && x.EmailAddresses[0].Address != null && x.EmailAddresses[0].Address.Contains('@')).ToList();

        return cacheContacts;
    }

我还找到了可以用于自动完成的 Exchange 服务 ResolveName