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

C#中如何遍历GraphServiceClient组成员响应映射到自定义模型

问题根因

你当前代码无法正常遍历赋值有4个核心原因:

  1. Groups.Members接口返回的是DirectoryObject类型的基类集合,默认可能包含用户、安全组、设备、服务主体等多种目录对象,不是直接的用户实体,直接遍历无法直接拿到用户属性。
  2. Microsoft Graph默认采用稀疏字段返回机制,你没有显式指定要返回的字段时,接口只会返回@odata.type这类基础元数据,你需要的对象ID(GUID)等属性不会包含在响应中,自然无法从AdditionalData中读取。
  3. 你使用了.Result同步阻塞异步请求,既存在线程死锁风险,也没有处理接口分页逻辑:当组成员数量超过100时,接口会分页返回结果,当前写法只会拿到第一页最多100条数据。
  4. 你要的对象全局唯一GUID本身就是Graph资源的强类型Id属性,不需要从AdditionalData字典中读取。
可直接运行的修复代码
public async Task<IActionResult> Index()
{
    var scopes = new[] { "https://graph.microsoft.com/.default" };
    var options = new TokenCredentialOptions
    {
        AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
    };
    var clientSecretCredential = new ClientSecretCredential(
        tenantId, clientId, clientSecret, options);
    var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

    List<CRMUsers> _users = new List<CRMUsers>();
    
    // 构造请求:筛选成员类型为用户,指定需要返回的字段
    var membersRequest = graphClient.Groups["替换为你的组对象ID"].Members
        .Request()
        // 过滤只保留用户类型成员,排除组、设备等其他目录对象
        .Filter("isOf('microsoft.graph.user')")
        // 显式声明需要返回的字段,按需添加即可
        .Select("id,displayName,mail,userPrincipalName");

    // 循环处理分页,拉取全量成员
    var currentPage = await membersRequest.GetAsync();
    while (currentPage?.Count > 0)
    {
        foreach (var dirObj in currentPage)
        {
            // 强转为User类型后直接取属性
            if (dirObj is User adUser)
            {
                _users.Add(new CRMUsers
                {
                    GUID = adUser.Id,
                    // 其他自定义模型字段按需映射即可,比如:
                    // DisplayName = adUser.DisplayName,
                    // Email = adUser.Mail
                });
            }
        }
        // 存在下一页则继续拉取,否则结束循环
        if (currentPage.NextPageRequest != null)
        {
            currentPage = await currentPage.NextPageRequest.GetAsync();
        }
        else
        {
            break;
        }
    }

    // 传递映射完成的自定义模型集合到视图
    return View(_users);
}
额外注意事项
  • 异步方法中禁止使用.Result、.Wait()这类同步阻塞调用,必须使用await关键字等待异步结果,否则很容易出现上下文死锁导致请求无响应。
  • 如果使用的是v5版本以上的新版Graph SDK,分页拉取可以直接用GetAllAsync()方法,不需要手动写循环处理NextPageRequest,代码会更简洁。
  • 如果确实需要读取未在SDK模型中定义的扩展属性,再从AdditionalData字典中取值,常规字段直接用强类型模型属性读取即可,性能和稳定性更好。
  • 如果你需要获取组内嵌套组下的成员,当前接口默认不会递归拉取,需要额外调用接口获取嵌套组的成员再做合并。

内容的提问来源于stack exchange,提问作者Jerwin Alimuin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 07:06:23