frankfralick
frankfralick

Reputation: 103

Access user.MemberOf with Microsoft Graph Client Library

Note: I originally posed this question in the client library repo and they responded that this is an issue in the service library, not the the .NET library.

During development we have been doing something like this to get a user's groups:

var user = await GraphClient.Users[userId].Request().Expand("memberOf").GetAsync();

The result of which was fed to a method that would use the presumably returned "NextPageRequest" object to get results beyond the current page. Our fake development user accounts, as well as early real users never had enough group memberships to require the NextPageRequest logic, and testing of it was forgotten about.

After getting users with 20+ groups it eventually became clear that making a request as detailed above returns one page worth of memberships but does not return a NextPageRequest to use in the options of subsequent requests. Your documentation around collections makes it seem like this is how it should be done.

As I'm sure you already know, a way that does work is like this:

List<Group> userGroups = await GraphClient.Users[userId].MemberOf.Request().GetAsync().CurrentPage.Where(p => p.GetType() == typeof(Microsoft.Graph.Group)).Cast<Microsoft.Graph.Group>().ToList();

This, as far as we have seen, returns all of the user's group memberships. If the intent is that Expand not be used with "memberOf", then it shouldn't work at all. Right now the old code worked fine for around 760 of the 800 users in the tenant, the remainder being the ones that write the checks :). If we were doing .Expand("memberOf") incorrectly, let me know please.

Also, GetMemberGroups works differently than MemberOf. What's the intent? Maybe doing something like GetMemberGroups(securityEnabledOnly = false, expandGroupInfo = false) might be clearer.

Upvotes: 8

Views: 6366

Answers (2)

user3720939
user3720939

Reputation: 119

After looking at it some, I found an answer that returns all the groups for the user.

public async Task<List<string>> GetCurrentUserGroups(GraphServiceClient graphClient)
    {
        var totalGroups = new List<string>();
        var groups = await graphClient.Me.MemberOf.Request().GetAsync();

        while (groups.Count > 0)
        {
            foreach (Group g in groups)
            {
                totalGroups.Add(g.DisplayName);
            }
            if (groups.NextPageRequest != null)
            {
                groups = await groups.NextPageRequest.GetAsync();
            }
            else
            {
                break;
            }
        }
        return totalGroups;
    }

Upvotes: 5

Dan Kershaw - MSFT
Dan Kershaw - MSFT

Reputation: 5838

Your observations are correct. $expand is somewhat limited in Directory, and will only expand up to 20 items and does not support pagination. This is not necessarily true for other Graph services. See https://graph.microsoft.io/en-us/docs/overview/query_parameters and $expand, where this is documented.

Unfortunately changing behavior to return an unsupported error for things like $expand=memberOf would represent a breaking change. We could consider this change for a new version.

We are also looking to add more annotations to the Graph metadata document that might be able to describe where expand and pagination is supported. This will also help limit the client library not to show options that the service cannot support.

Hope this helps,

Upvotes: 1

Related Questions