mr.coffee
mr.coffee

Reputation: 1028

Microsoft Graph API call hangs indefinitely

I am attempting to query Azure Active Directory User information using Microsoft Graph. I can authenticate fine but when I attempt to query user information client.Users my application hangs indefinitely: no timeout, no error, just hangs. I found this post however the suggestions there did not help me.

public bool GetUserByUniqueID(string uid, out GraphUser user)
{
    bool ret = false;
    user = new GraphUser();
    if (Authenticate(out AuthToken token))
    {
        GraphServiceClient client = GetGraphServiceClient(token);
        // The below code hangs indefinitely
        User user = client.Users[uid].Request().Select(GraphProperties).GetAsync().GetAwaiter().GetResult();
        if (user != null)
        {
            MapGraphUser(ret, user);            
            ret = true;
        }
    }
    return ret;
}

private bool Authenticate(out AuthToken token)
{
    bool ret = false;
    token = new AuthToken();
    string url = $"https://login.microsoftonline.com/{_tenant}/oauth2/v2.0/token";
    RestClient client = new RestClient(url);
    RestRequest request = new RestRequest(Method.POST);
    request.Parameters.Add(new Parameter("grant_type", _grantType, ParameterType.GetOrPost));
    request.Parameters.Add(new Parameter("scope", _scope, ParameterType.GetOrPost));
    request.Parameters.Add(new Parameter("client_secret", _clientSecret, ParameterType.GetOrPost));
    request.Parameters.Add(new Parameter("client_id", _clientId, ParameterType.GetOrPost));
    IRestResponse response = client.Execute<AuthToken>(request);
    if (response.StatusCode == HttpStatusCode.OK)
    {
        token = JsonConvert.DeserializeObject<AuthToken>(response.Content);
        ret = true;
    }
    return ret;
}

Update 5/2/2019

Reverting Microsoft.Graph and Microsoft.Graph.Core to version 1.12 allows me to call .GetAwaiter().GetResult() within a synchronous context.

Update 11/18/2020

I have refactored my code to use async/await pattern with the latest version of Microsoft.Graph and Microsoft.Graph.Core.

public async Task<GraphUser> GetUserByUniqueID(string uid)
{
    GraphUser ret = new GraphUser();    
    if (Authenticate(out AuthToken token))
    {
        GraphServiceClient client = GetGraphServiceClient(token);
        User user = await client.Users[uid].Request().Select(GraphProperties).GetAsync();
        if (user != null)
        {
            MapGraphUser(ret, user);            
            ret.Found = true;
        }
    }   
    return ret;
}

Upvotes: 6

Views: 5487

Answers (3)

SteveP
SteveP

Reputation: 435

I had the same issue when trying to get a list of sites, but I was using Microsoft.Graph V 4.47.0 and Microsoft.Graph.Core V 2.0.14, from within a MVC Web project. I was also using await.

            var drives = await graphClient.Sites["root"].Lists
            .Request()
            .GetAsync();

The above just hangs. Changing to:

            var drives = graphClient.Sites["root"].Lists
            .Request()
            .GetAsync()
            .GetAwaiter()
            .GetResult();

works as expected.

Full Code:

        public async Task GetDrives(GraphServiceClient graphClient)
    {
        AuthenticationConfig config = AuthenticationConfig.ReadFromJsonFile("appsettings.json");
        O365Drives = new List<MyDriveInfo>();


        var drives = graphClient.Sites["root"].Lists
            .Request()
            .GetAsync()
            .GetAwaiter()
            .GetResult();

        foreach (var item in drives)
        {
            O365Drives.Add(new MyDriveInfo
            {
                Id = item.Id,
                Name = item.Name,
                WebUrl = item.WebUrl,
                CreatedOn = item.CreatedDateTime,
                ModifiedOn = item.LastModifiedDateTime
            });
        }
    }

The above is called by firing an Ajax POST request when clicking on a button.

In another project, a console app, using Microsoft.Graph V 4.34.0 and Microsoft.Graph.Core V 2.0.9

var drives = await graphClient.Sites["root"].Lists
        .Request()
        .GetAsync();

Works as expected.

Full Code:

        private static async Task GetDrives(GraphServiceClient graphClient)
    {
        AuthenticationConfig config = AuthenticationConfig.ReadFromJsonFile("appsettings.json");
        myFileInfo.O365Drives = new List<MyDriveInfo>();

        var drives = await graphClient.Sites[$"{config.SiteID}"].Lists
            .Request()
            .GetAsync();

        foreach(var item in drives)
        {
            myFileInfo.O365Drives.Add(new MyDriveInfo
            {
                Id = item.Id,
                Name = item.Name,
                WebUrl = item.WebUrl,
                CreatedOn = item.CreatedDateTime,
                ModifiedOn = item.LastModifiedDateTime
            });
        }
    }

The above is called by either running the console app manually or from a scheduled task.

I just thought I'd post my findings for the newer versions of Microsoft.Graph for anyone else having similar issues.

Upvotes: 0

gMoney
gMoney

Reputation: 235

I was having the same issue. I found on another article somewhere that it had something to do with two task waiting to finish at once. i cant find that article now.

For me .GetAwaiter().GetResult(); was working within a scheduled job but not as a manual button press task.

as a result of playing around with it. What worked for me was replacing .GetAwaiter().GetResult() with await. (i'm not sure why this fixed it but it did)

From:

var results = graphServiceClient.Users[uid].Request().GetAsync().GetAwaiter().GetResult();

To:

var results = await graphServiceClient.Users[uid].Request().GetAsync();

Hope this helps someone in the future

Upvotes: 4

Arie Schwartzman
Arie Schwartzman

Reputation: 1

I'm having the same issue with NPM package of the Graph API. Reverted to plain old request-promise. Now it's not stuck but does not always find the members of a group. Using beta version of the API works fine

Upvotes: 0

Related Questions