gtrivedi
gtrivedi

Reputation: 515

Microsoft Graph only returning the first 100 Users

I have the below code which returns all users based on a filter. The problem is it only returns 100 users but I know there are a lot more.

private List<User> GetUsersFromGraph()
{
    if (_graphAPIConnectionDetails == null) ReadParametersFromXML();
    if (graphServiceClient == null) graphServiceClient = CreateGraphServiceClient();

    var users = graphServiceClient
        .Users
        .Request()
        .Filter(_graphAPIConnectionDetails.UserFilter)
        .Select(_graphAPIConnectionDetails.UserAttributes)
        .GetAsync()
        .Result
        .ToList<User>();

    return users;
}

the method returns only 100 user objects. My Azure portal admin reports there should be closer to 60,000.

Upvotes: 9

Views: 9944

Answers (2)

stephen ebichondo
stephen ebichondo

Reputation: 345

I had a similar use case where the return of my query was > 100.

    final GroupCollectionPage userGroups = _appClient.users({id})
            .memberOfAsGroup()
            .buildRequest(requestOptions)
            .select("displayName,id,mail")
            .filter("startswith(displayName, 'c')")
            .orderBy("displayName")
            .get();

So I could easily iterate over the result set

    // Output each Group details
    for (Group usergroup : userGroups.getCurrentPage()) {
        System.out.println("  User Group Name: " + usergroup.displayName);
        System.out.println("  ID: " + usergroup.id);
        System.out.println(" Email: " + usergroup.mail);
    }

Here's how to get the next page of the user groups

  public static void getGroups() {
    LinkedList<Option> requestOptions = new LinkedList<Option>();
    requestOptions.add(new HeaderOption("ConsistencyLevel", "eventual"));
    requestOptions.add(new QueryOption("$count", "true"));

    GroupCollectionPage userGroups = _appClient.users({id})
            .memberOfAsGroup()
            .buildRequest(requestOptions)
            .select("displayName,id,mail")
            .filter("startswith(displayName, 'c')")
            .orderBy("displayName")
            .get();

    List<Group> allGroupsList = new ArrayList<>();

    do {
        List<Group> currentPageGroup = userGroups.getCurrentPage();
        allGroupsList.addAll(currentPageGroup);
        GroupCollectionRequestBuilder nextPage = userGroups.getNextPage();
        userGroups = nextPage == null ? null : nextPage.buildRequest().get();
    } while (userGroups != null);

    System.out.println("Total Group count is :" + allGroupsList.size());

    for (Group usergroup : allGroupsList) {
        System.out.println("  User Group Name: " + usergroup.displayName);
        System.out.println("  ID: " + usergroup.id);
        System.out.println("  Email: " + usergroup.mail);
    }
}

Upvotes: 0

Marc LaFleur
Marc LaFleur

Reputation: 33094

Most of the endpoints in Microsoft Graph return data in pages, this includes /users.

In order to retrieve the rest of the results you need to look through the pages:

private async Task<List<User>> GetUsersFromGraph()
{
    if (_graphAPIConnectionDetails == null) ReadParametersFromXML();
    if (graphServiceClient == null) graphServiceClient = CreateGraphServiceClient();

    // Create a bucket to hold the users
    List<User> users = new List<User>();

    // Get the first page
    IGraphServiceUsersCollectionPage usersPage = await graphClient
        .Users
        .Request()
        .Filter("filter string")
        .Select("property string")
        .GetAsync();

    // Add the first page of results to the user list
    users.AddRange(usersPage.CurrentPage);

    // Fetch each page and add those results to the list
    while (usersPage.NextPageRequest != null)
    {
        usersPage = await usersPage.NextPageRequest.GetAsync();
        users.AddRange(usersPage.CurrentPage);
    }

    return users;
}

One super important note here, this method is the lest performant way to retrieve data from Graph (or any REST API really). Your app will be sitting there for a long time while it downloads all this data. The proper methodology here is to fetch each page and process just that page before fetching additional data.

Upvotes: 20

Related Questions