You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用Microsoft Graph API获取Azure AD用户时出现ODataError异常

Azure AD调用Microsoft Graph获取用户时出现ODataError的解决方案

错误信息

System.AggregateException: One or more errors occurred. (Exception of type 'Microsoft.Graph.Models.ODataErrors.ODataError' was thrown.)
 ---> Microsoft.Graph.Models.ODataErrors.ODataError: Exception of type 'Microsoft.Graph.Models.ODataErrors.ODataError' was thrown.
   at Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.ThrowIfFailedResponse(HttpResponseMessage response, Dictionary`2 errorMapping, Activity activityForAttributes)
   at Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.SendAsync[ModelType](RequestInformation requestInfo, ParsableFactory`1 factory, Dictionary`2 errorMapping, CancellationToken cancellationToken)
   at Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.SendAsync[ModelType](RequestInformation requestInfo, ParsableFactory`1 factory, Dictionary`2 errorMapping, CancellationToken cancellationToken)
   at Microsoft.Graph.Users.UsersRequestBuilder.GetAsync(Action`1 requestConfiguration, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at Xlp.Domain.Services.GraphService1.GetAllUsersAsync() in C:\Users\Shashikantpawar\Desktop\XLP\backend\src\XLP.Domain\Services\GraphService1.cs:line 26
   at Xlp.Api.Controllers.ClientsController.Get() in C:\Users\Shashikantpawar\Desktop\XLP\backend\src\Xlp.Api\Controllers\V1\ClientsController.cs:line 40
   at lambda_method5(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

HEADERS
=======
Accept: */*
Connection: keep-alive
Host: localhost:5224
User-Agent: PostmanRuntime/7.28.4
Accept-Encoding: gzip, deflate, br
Postman-Token: 2bb4e39a-686e-4072-af4f-9c85b3760bc2

原代码

public async Task<List<Microsoft.Graph.Models.User>> GetAllUsersAsync()
{
    var clientId = _configuration.GetValue<string>("AzureAd:ClientId");
    var tenantId = _configuration.GetValue<string>("AzureAd:TenantId");
    var clientSecret = _configuration.GetValue<string>("AzureAd:ClientSecret");

    var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
    GraphServiceClient graphServiceClient = new GraphServiceClient(clientSecretCredential);

    var users = graphServiceClient.Users.GetAsync().Result;
    return users.Value;
}

解决步骤

1. 配置正确的应用权限

客户端凭据模式(无用户上下文)需要使用Application类型的权限,且必须由管理员同意:

  • 登录Azure门户,进入Azure AD -> 应用注册 -> 你的应用
  • 切换到API权限,点击添加权限 -> 选择Microsoft Graph -> 应用权限
  • 搜索并添加User.Read.All权限,然后点击授予管理员同意(必须完成此步骤,否则权限不生效)

2. 修复异步调用问题

原代码使用.Result阻塞异步任务,会导致异常被包装在AggregateException中,无法直接查看ODataError的具体详情。改用await调用:

public async Task<List<Microsoft.Graph.Models.User>> GetAllUsersAsync()
{
    var clientId = _configuration.GetValue<string>("AzureAd:ClientId");
    var tenantId = _configuration.GetValue<string>("AzureAd:TenantId");
    var clientSecret = _configuration.GetValue<string>("AzureAd:ClientSecret");

    var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
    GraphServiceClient graphServiceClient = new GraphServiceClient(clientSecretCredential);

    var users = await graphServiceClient.Users.GetAsync();
    return users.Value;
}

3. 验证凭据正确性

确认配置文件中的ClientId、TenantId、ClientSecret完全匹配Azure应用注册中的信息:

  • ClientId是应用的"应用程序(客户端)ID"
  • TenantId是目录(租户)ID
  • ClientSecret是在应用注册证书和密码中生成的客户端密码,不是密钥ID

4. 捕获并解析ODataError详情

添加异常捕获逻辑,获取具体错误码和描述,便于精准排查:

public async Task<List<Microsoft.Graph.Models.User>> GetAllUsersAsync()
{
    var clientId = _configuration.GetValue<string>("AzureAd:ClientId");
    var tenantId = _configuration.GetValue<string>("AzureAd:TenantId");
    var clientSecret = _configuration.GetValue<string>("AzureAd:ClientSecret");

    var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
    GraphServiceClient graphServiceClient = new GraphServiceClient(clientSecretCredential);

    try
    {
        var users = await graphServiceClient.Users.GetAsync();
        return users.Value;
    }
    catch (Microsoft.Graph.Models.ODataErrors.ODataError odataError)
    {
        // 记录或输出具体错误信息
        var errorCode = odataError.Error.Code;
        var errorMessage = odataError.Error.Message;
        throw new InvalidOperationException($"Graph API调用失败: {errorCode} - {errorMessage}", odataError);
    }
}

内容的提问来源于stack exchange,提问作者Shashikant Pawar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 00:07:47