Microsoft Azure Active Directory:展开管理器NullReferenceException

时间:2017-03-30 07:13:51

标签: azure-active-directory microsoft-graph

Microsoft Azure Active Directory 2.1.1图形客户端有一个错误: 在Azure AD中,我们有没有经理的用户。 当批处理请求获取特定用户和扩展管理器时,如果没有经理设置,我们会在响应反序列化期间获得 Object null引用异常 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) .... 似乎这个图形客户端不是开源的,我们无法直接修复它。

代码导致问题:

//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); 

因为 ExecuteBatchAsync 获取OperationResopnce并为每个响应创建pagedcollection,但此集合的初始化并不是惰性的。 因此,如果一个集合中的某些错误将阻止所有响应

有谁知道如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

要通过Microsoft Graph获取用户管理员,您可以参考以下代码:

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

如果没有该用户的管理员,该库也会抛出异常。我们需要捕获并处理异常。例如,下面的代码打印用户的经理,如果没有经理只是打印消息,就像用户没有经理一样:

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!");
    }
}

答案 1 :(得分:0)

因此,如果有人面临相同的情况,并且在使用新库重写生产代码的时间有限的情况下 - 会有解决方法来执行此类批量请求。 只需使用以下方式执行批处理请求:

   activeDirectoryClient.Context.ExecuteBatch()

更详细的例子: var result = activeDirectoryClient.Context.ExecuteBatch(); foreach (QueryOperationResponse batchElementResult in result) { try { var userWithManager = batchElementResult.FirstOrDefault(); } catch (NullReferenceException) { //ignore single user. not all batch } }

但是当然最好考虑使用开源更轻量级的客户端,如Fei Xue建议的那样 - MSFT https://github.com/microsoftgraph/msgraph-sdk-dotnet/blob/master/docs/