Azure active directory Microsoft Azure Active Directory:展开管理器NullReferenceException

Azure active directory Microsoft Azure Active Directory:展开管理器NullReferenceException,azure-active-directory,microsoft-graph-api,Azure Active Directory,Microsoft Graph Api,graph client有一个错误: 在Azure广告中,我们有没有管理员的用户。 当批量请求获取特定用户和展开管理器时,如果未设置管理器,则在响应反序列化过程中会出现对象空引用异常: 位于Microsoft.Azure.ActiveDirectory.GraphClient.Internal.DirectoryObject.set\u管理器(DirectoryObject值) 在lambda_方法(闭包、对象、对象) 位于System.Data.Services.Client.Metadat

graph client有一个错误: 在Azure广告中,我们有没有管理员的用户。 当批量请求获取特定用户和展开管理器时,如果未设置管理器,则在响应反序列化过程中会出现对象空引用异常:

位于Microsoft.Azure.ActiveDirectory.GraphClient.Internal.DirectoryObject.set\u管理器(DirectoryObject值)
在lambda_方法(闭包、对象、对象)
位于System.Data.Services.Client.Metadata.ClientPropertyAnnotation.SetValue(对象实例、对象值、字符串propertyName、布尔Allowad)
位于System.Data.Services.Client.Materialization.EntryValueMaterializationPolicy.MaterializeResolveEntry(MaterializerEntry,布尔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获取OperationResopance并为每个响应创建pagedcollection,但此集合的初始化不是惰性的。 因此,如果一个集合中出现错误,所有响应都将被阻止


有人知道如何解决这个问题吗

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

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

因此,如果有人面临同样的情况,并且使用新库重写生产代码的时间有限,那么将有解决方法来执行此类批处理请求。 只需使用以下命令执行批处理请求:

   activeDirectoryClient.Context.ExecuteBatch()
更详细的示例:

var result=activeDirectoryClient.Context.ExecuteBatch();
foreach(QueryOperationResponse BatchElement结果中的结果)
{
尝试
{
var userWithManager=batchElementResult.FirstOrDefault();
}
捕获(NullReferenceException)
{
//忽略单个用户。不是所有批处理
}
}


当然,最好考虑使用开源软件,如FEX-MSFFT

所建议的那样,你使用的是什么版本的图书馆?如果您可以共享代码,这样我们就可以使用Azure Graph REST替换客户端库作为解决方案。版本2.1.1代码非常简单,只需按对象id获取用户并展开管理器即可。这里很可能存在错误。也就是说,我强烈建议您使用Microsoft Graph而不是Azure AD Graph API来访问Azure Active Directory资源。我们的开发工作现在主要集中在包括Azure AD功能的微软图形上。您建议使用什么样的客户端库?OK,我们将考虑使用图形客户端库。至少它是开源的,如果出现bug,我们能够修复它。