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

获取不含子组的Active Directory组用户的C#代码报错问题

解决Active Directory组用户获取时的NullReferenceException问题

看起来你遇到的问题核心是当组包含子组时,你的数组里混入了null元素,导致后续Split操作触发空引用异常。咱们一步步来拆解和修复:

错误原因分析

在GetAllUsersFromGroup方法里,你初始化了一个固定大小的数组deResultsArray,但只有当遍历到的member是用户时,才会给数组的对应位置赋值。如果遇到子组(非用户对象),该位置就会保留默认值null。当sortLDAPUsers方法循环处理这个数组时,碰到null的元素调用Split('~'),自然就抛出NullReferenceException了。

另外,你的需求是只获取当前组直接包含的用户,不需要子组里的用户,所以我们需要确保只收集用户对象,并且避免集合里出现空值。

修复后的代码

下面是调整后的完整代码,主要改动是用List<string>替代固定数组,同时优化用户判断逻辑:

public List<string> GetAllUsersFromGroup(string domain, string group)
{
    List<string> retVal = new List<string>();
    List<string> userEntries = new List<string>(); // 改用List存储有效用户项,避免null

    using (DirectoryEntry entry = new DirectoryEntry(domain))
    using (DirectorySearcher searcher = new DirectorySearcher(entry, $"(&(objectCategory=Group)(cn={group}))"))
    {
        searcher.SearchScope = SearchScope.Subtree;
        SearchResult result = searcher.FindOne();

        if (result == null)
        {
            // 处理组不存在的情况
            retVal.Add("<tr><td>Group not found</td><td>&nbsp;</td></tr>");
            return retVal;
        }

        foreach (string member in result.Properties["member"])
        {
            using (DirectoryEntry de = new DirectoryEntry($"{domain}/{member}"))
            {
                // 严谨判断:确认是用户对象,且displayName和cn属性存在
                if (de.Properties["objectClass"].Contains("user") 
                    && de.Properties["displayName"].Count > 0 
                    && de.Properties["cn"].Count > 0)
                {
                    string userInfo = $"{de.Properties["displayName"][0]}~{de.Properties["cn"][0]}";
                    userEntries.Add(userInfo);
                }
            }
        }
    }

    if (userEntries.Count == 0)
    {
        retVal.Add("<tr><td>Group has no members</td><td>&nbsp;</td></tr>");
    }
    else
    {
        userEntries.Sort(); // 直接对List排序,简化逻辑
        foreach (string userInfo in userEntries)
        {
            string[] parts = userInfo.Split('~');
            retVal.Add($"<tr><td>{parts[0]}</td><td>{parts[1]}</td></tr>");
        }
    }

    return retVal;
}

// 原来的sortLDAPUsers方法可以删掉了,因为逻辑已经整合到上面

关键改动说明

  • 用List<string>替代固定数组:避免了数组中出现未赋值的null元素,只收集符合条件的用户项。
  • 添加using语句管理资源:DirectoryEntry和DirectorySearcher是IDisposable对象,用using确保资源及时释放,避免内存泄漏。
  • 严谨的属性存在性判断:在获取displayName和cn之前,先检查属性是否存在,避免因属性缺失导致的异常。
  • 简化排序和拼接逻辑:直接对用户列表排序,然后循环拼接HTML行,去掉了复杂的数组拆分逻辑,代码更易读。
  • 增加组不存在的处理:如果searcher.FindOne()返回null,直接提示组不存在,增强鲁棒性。

这样修改后,无论是纯用户组还是包含子组的组,都能正确过滤出直接成员中的用户,不会再触发空引用异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:32:18