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

Blazor Server中用Graph API获取Azure AD全量用户遇分页及注入错误

Blazor Server中使用Graph API分页获取全量Azure AD用户

问题原因

你遇到的错误核心是静态方法无法直接访问Blazor注入的GraphServiceClient实例,依赖注入的服务仅能在非静态的类/方法中通过构造函数或组件注入获取。同时原代码的分页逻辑可进一步优化效率。

正确实现方案

1. 先确认Graph服务已注册(Program.cs)

确保在启动类中完成GraphServiceClient的依赖注入配置:

using Microsoft.Graph;
using Microsoft.Identity.Web;

var builder = WebApplication.CreateBuilder(args);

// 根据你的权限模式(用户委派/客户端凭据)注册Graph服务
builder.Services.AddMicrosoftGraph(builder.Configuration.GetSection("AzureAd"));

// 其他Blazor服务配置
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();

var app = builder.Build();

// 中间件配置...
app.Run();

2. 分页获取全量用户的实现

方式一:在Blazor组件中直接实现

@page "/user-selector"
@inject GraphServiceClient GraphClient
@using Microsoft.Graph.Models
@using Microsoft.Graph

<h3>Azure AD 用户选择</h3>

<select>
    @foreach (var user in UserList)
    {
        <option value="@user.Id">@user.DisplayName (@user.UserPrincipalName)</option>
    }
</select>

@code {
    private List<User> UserList = new();

    protected override async Task OnInitializedAsync()
    {
        UserList = await GetAllAzureAdUsersAsync();
    }

    private async Task<List<User>> GetAllAzureAdUsersAsync()
    {
        var allUsers = new List<User>();
        // 单次请求拉取最大999条数据,减少分页次数
        var initialPage = await GraphClient.Users.GetAsync(config =>
        {
            // 只获取需要的字段,优化性能
            config.QueryParameters.Select = new[] { "id", "displayName", "userPrincipalName" };
            config.QueryParameters.Top = 999;
        });

        // 创建分页迭代器自动处理后续页
        var pageIterator = PageIterator<User, UserCollectionResponse>.CreatePageIterator(
            GraphClient,
            initialPage,
            user =>
            {
                allUsers.Add(user);
                return true; // 返回true表示继续迭代所有页
            });

        await pageIterator.IterateAsync();
        return allUsers;
    }
}

方式二:封装为可复用服务(推荐)

创建UserService.cs:

using Microsoft.Graph;
using Microsoft.Graph.Models;

public class UserService
{
    private readonly GraphServiceClient _graphClient;

    // 通过构造函数注入GraphServiceClient
    public UserService(GraphServiceClient graphClient)
    {
        _graphClient = graphClient;
    }

    public async Task<List<User>> GetAllAzureAdUsersAsync()
    {
        var allUsers = new List<User>();
        var initialPage = await _graphClient.Users.GetAsync(config =>
        {
            config.QueryParameters.Select = new[] { "id", "displayName", "userPrincipalName" };
            config.QueryParameters.Top = 999;
        });

        var pageIterator = PageIterator<User, UserCollectionResponse>.CreatePageIterator(
            _graphClient,
            initialPage,
            user =>
            {
                allUsers.Add(user);
                return true;
            });

        await pageIterator.IterateAsync();
        return allUsers;
    }
}

在Program.cs中注册服务:

builder.Services.AddScoped<UserService>();

组件中调用服务:

@page "/user-selector"
@inject UserService UserService
@using Microsoft.Graph.Models

<select>
    @foreach (var user in UserList)
    {
        <option value="@user.Id">@user.DisplayName (@user.UserPrincipalName)</option>
    }
</select>

@code {
    private List<User> UserList = new();

    protected override async Task OnInitializedAsync()
    {
        UserList = await UserService.GetAllAzureAdUsersAsync();
    }
}

关键注意点

  • 禁止在静态方法中使用注入的服务实例,必须通过构造函数或组件注入获取GraphServiceClient。
  • 使用Top=999可最大化单页数据量,减少分页请求次数。
  • 按需指定Select字段,避免拉取冗余数据,提升接口响应速度。
  • 确保应用已获得User.Read.All权限(需在Azure AD门户中配置并完成授权)。

内容的提问来源于stack exchange,提问作者Srinidhi S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 10:13:35