Pak
Pak

Reputation: 2766

Retrieve suggested contacts of Outlook

My company is under Office 365. My goal is to retrieve Outlook's suggested contacts of the user in my asp .net MVC app (the contacts displayed in the autocomplete list). The website is configured for automatic logon with Windows Authentication and I don't want to ask the user his credentials.

I have to tried to retrieve the suggested contacts by using Exchange Web Service but I only succeed to retrieve "real" contacts by using this code :

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;
}

Then, I tried by using the 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("[email protected]", "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();
    }

Upvotes: 2

Views: 1028

Answers (2)

Pak
Pak

Reputation: 2766

I never found the "Suggested Contacts" folder of the post. I ended by using the folder "AllContacts" that seems to do the job.

    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;
    }

I also found the service ResolveName of Exchange that I could have use for the autocomplete.

Upvotes: 1

Benoit Patra
Benoit Patra

Reputation: 4545

About the Suggested Contact problem

What I am thinking is that you are not looking in the proper folder. From what I have seen by googling the suggested contacts are not in the Contacts directory but in Suggested Contacts. In your EWS sample you are looking in Contacts... See this discussion. Look also at this guy post, he manages to have access to the Suggested Contacts folder with EWS and powershell so there is no doubt this is feasible with C# and EWS .NET SDK. My advice is to continue trying with your sample 1.

About the Authentication problem

Let me emphasize the fact that your requests should be authorized to access both Exchange Web Services (code sample 1) or the outlook REST API (code sample 2).

In sample 1 we do not see how the _service field is instantiated but I bet there is a piece of code that looks more or less the lines below so your allowed to request EWS.

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

The token can be probably reuse for the Outlook REST API, try to set it in the bearer in the httpClient

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

Now your request should be authorized but you still have your proxy problem. I bet that this happen only within your organisation because your IT set up a proxy. You probably won't need it in production. You can use a debug statement to make it work while your developing locally.

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

Upvotes: 1

Related Questions