获取不含子组的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> </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> </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
相关产品推荐
相关产品推荐

