1
votes

Microsoft Azure Active Directory 2.1.1 graph client has a bug: In Azure AD we have user without manager. When do batch requests to get specific users and expand manager we get Object null reference exception during response deserialization in case where no manager set: at Microsoft.Azure.ActiveDirectory.GraphClient.Internal.DirectoryObject.set_manager(DirectoryObject value) at lambda_method(Closure , Object , Object ) at System.Data.Services.Client.Metadata.ClientPropertyAnnotation.SetValue(Object instance, Object value, String propertyName, Boolean allowAdd) at System.Data.Services.Client.Materialization.EntryValueMaterializationPolicy.MaterializeResolvedEntry(MaterializerEntry entry, Boolean includeLinks) .... Seems this graph client is not open source we cannot fix that directly.

The code cause the problem:

//No manager for this user.
var query1 = activeDirectoryClient.Users.Where(t => t.ObjectId == "id1")
.Expand(t=>t.Manager);
var query2 = activeDirectoryClient.Users.Where(t => t.ObjectId == "id2")
.Expand(t => t.Manager);
var query3 = activeDirectoryClient.Users.Where(t => t.ObjectId == "id3")
.Expand(t=>t.Manager);
var query4 = activeDirectoryClient.Users.Where(t => t.ObjectId == "id4")
.Expand(t=>t.Manager);
// this line will throw exception.
var result = await activeDirectoryClient.Context.ExecuteBatchAsync(query1, query2, query3, query4); 

Because ExecuteBatchAsync gets OperationResopnce and create pagedcollection for each response but initialization of this collection is not lazy. so if some error in one collection all responces will be blocked

Does anyone know how to workaround this?

2
What's version of library are you using? And it is helpful if you can share the code so that we can use the Azure Graph REST to replace the client library as a workaround. - Fei Xue - MSFT
Version 2.1.1 code is very simple just get user by object id and expand manager. - Ilya
There may very well be a bug here. That said, I strongly recommend that you use Microsoft Graph instead of Azure AD Graph API to access Azure Active Directory resources. Our development efforts are now concentrated on Microsoft Graph which includes Azure AD functionality. - Marc LaFleur
And what client library do you suggest to use? - Ilya

2 Answers

2
votes

To get the manager of user via Microsoft Graph, you can refer the code below:

var manager = (Microsoft.Graph.User)graphserviceClient.Me.Manager.Request().GetAsync().Result;

And if there is no manager for the user, this library also throw the exception. We need to catch and handle the exception. For example, the code below prints the user's manager and if no manger just print the message like user has no manager:

var accessToken = "";
var graphserviceClient = new GraphServiceClient(
new DelegateAuthenticationProvider(
(requestMessage) =>
{
   requestMessage.Headers.Authorization = new  AuthenticationHeaderValue("bearer", accessToken);
   return Task.FromResult(0);
}));

string[] userIds = { "fe989a2b-81d1-48ca-aa15-0ac52688f65b", "c2ca48ba-1608-4254-b377-ba514276fe75" };
foreach(var id in userIds)
{
    try
    {
        var manager = (Microsoft.Graph.User)graphserviceClient.Users[id].Manager.Request().GetAsync().Result;
        Console.WriteLine($"user {id}'s manager is {manager.DisplayName}!");
    }
    catch(Exception ex) {

        Console.WriteLine($"user {id} has no manager!");
    }
}
0
votes

So if someone face with the same situation and will be limited in time to rewrite production code using new library - there will workaround to do such batch requests. Just do batch requests using:

   activeDirectoryClient.Context.ExecuteBatch()

More detailed example: var result = activeDirectoryClient.Context.ExecuteBatch(); foreach (QueryOperationResponse batchElementResult in result) { try { var userWithManager = batchElementResult.FirstOrDefault(); } catch (NullReferenceException) { //ignore single user. not all batch } }

But of course better consider using opensource more light weight client as was suggested by Fei Xue - MSFT https://github.com/microsoftgraph/msgraph-sdk-dotnet/blob/master/docs/