5

Given a query for members of a particular directory role, I would like to return a list of corresponding users. What I have is this:

IDirectoryObjectCollectionWithReferencesRequest request = graphServiceClient.directoryRoles(roleId).members().buildRequest();
IDirectoryObjectCollectionWithReferencesPage page = request.select(USER_FIELDS_TO_RETURN).get();
List<DirectoryObject> objects = page.getCurrentPage();
IDirectoryObjectCollectionWithReferencesRequestBuilder builder = page.getNextPage();
while (builder != null) {
    request = builder.buildRequest();
    page = request.select(USER_FIELDS_TO_RETURN).get();
    objects.addAll(page.getCurrentPage());
    builder = page.getNextPage();
}
return objects.stream().filter(o -> o.oDataType.equals("#microsoft.graph.user")).map(o -> new User()).collect(Collectors.toList());

The question lies in the return statement. Filter on only user objects (couldn't find a more elegant way of doing this than comparing the oDataType) and return the user object with the contents of o:

objects.stream().filter(o -> o.oDataType.equals("#microsoft.graph.user")).map(o -> {
        // the only thing that I could think of is to do some weird
        // serialization/deserialization logic here which is a bad solution
        // for anything other than a small number of elements
}).collect(Collectors.toList());

what is the correct way of converting DirectoryObject to User

xeros
  • 123
  • 8
StackMonkey
  • 107
  • 1
  • 7

3 Answers3

2

Microsoft Graph does not currently support this requirement.

If you're checking a specific directoryRole, you could come at this from the other direction. The /members endpoint does support filtering by member id:

v1.0/directoryRoles/{role-id}/members?$filter=id eq '{user-id}'

Please check the answers and workarounds provided in this thread. How to get admin roles that I am a member of, from Microsoft Graph using .Net Client SDK?

Marilee Turscak - MSFT
  • 7,367
  • 3
  • 18
  • 28
  • The problem is with casting data to specific objects. The return value is DirectoryObject which contains what I need. However, in order to make DirectoryObject into a User object you have to get the string of the raw value and serialize it to a User object. This operation isn’t particularly cheap when performed on a huge dataset. Is there a different way to get the User object out of the DirectoryObject? – StackMonkey Jan 09 '19 at 02:57
  • Or maybe a better question is; Can you instruct the sdk to return the User object shape rather than the DirectoryObject shape? Something along the lines of: graphServiceClient.directoryRoles(roleId).members(User.class).buildRequest() – StackMonkey Jan 09 '19 at 17:09
1

I know this is an old question, but I had the same problem and found a better solution.

You can actually convert it to a user after you have the list. So if you are iterating through the list:

var myDirectoryList = (List<DirectoryObject>)myRetrievedList;
foreach(var item in myDirectoryList)
{
    var myUser = (User)item;
    Console.WriteLine($"My name is {myUser.GivenName}");
}

Where DirectoryObject is Microsoft.Graph.DirectoryObject and User is Microsoft.Graph.User.

Scott Craig
  • 275
  • 2
  • 10
1

Just had the same problem, so, for anyone getting there, here is what i did (And i could not find any other simple solution...).

What you call "some weird serialization/deserialization logic" can actually be done this way using the DefaultSerializer :

private ISerializer serializer = new DefaultSerializer(new DefaultLogger());
...
objects.stream().filter(o -> o.oDataType.equals("#microsoft.graph.user")).map(o -> {
    return serializer.deserializeObject(o.getRawObject().toString(), User.class)
}).collect(Collectors.toList());