DirectorySearcher.FindAll()方法中的foreach循环

本文关键字:foreach 循环 方法 FindAll DirectorySearcher | 更新日期: 2023-09-27 18:20:22

我需要在DirectorySearcher.FindAll()中运行一个foreach循环并获取displayname属性。这似乎有内存问题(参考链接:使用DirectorySearcher.FindAll()时内存泄漏)。我的代码如下:

List<string> usersList = new List<string>();
        string displayName = string.Empty;
        try
        {
            using (DirectoryEntry directoryEntry = new DirectoryEntry(ldap, userName, password))
            {
                DirectorySearcher directorySearcher = new DirectorySearcher(directoryEntry);
                directorySearcher.PageSize = 500;  // ADD THIS LINE HERE !
                string strFilter = "(&(objectCategory=User))";
                directorySearcher.PropertiesToLoad.Add("displayname");//first name
                directorySearcher.Filter = strFilter;
                directorySearcher.CacheResults = false;
                SearchResult result;
                var resultOne = directorySearcher.FindOne();
                using (var resultCol = directorySearcher.FindAll())
                {
                    for (int counter = 0; counter < resultCol.Count; counter++)
                    {
                        result = resultCol[counter];
                        if (result.Properties.Contains("displayname"))
                        {
                            displayName = (String)result.Properties["displayname"][0];
                            usersList.Add(displayName);
                        }
                    }
                } 
            }
        }

有什么可能循环的方法吗。我也尝试过调用Dispose()方法,但它不起作用。非常感谢您的帮助。

DirectorySearcher.FindAll()方法中的foreach循环

这是我为我正在进行的一个项目提出的一个解决方案,我认为它对您有效。我的解决方案循环搜索结果,并在最多20个字符串的列表中返回显示名称。

using (DirectorySearcher ds = new DirectorySearcher())
        {
            //My original filter
            //ds.Filter = string.Format("(|(&(objectClass=group)(|(samaccountname=*{0}*)(displayname=*{0}*)))(&(objectCategory=person)(objectClass=user)(|(samaccountname=*{0}*)(displayname=*{0}*))))", name);
            //Your Modified filter                
            ds.filter = "(objectCategory=User)"

            ds.PropertiesToLoad.Add("displayname");
            ds.SizeLimit = 20;
            SearchResultCollection result = ds.FindAll();
            List<string> names = new List<string>();
            foreach (SearchResult r in result)
            {
                var n = r.Properties["displayname"][0].ToString();
                if (!names.Contains(n))
                    names.Add(n);
            }
            return Json(names, JsonRequestBehavior.AllowGet);
        }

如果它在托管代码中不是有效的解决方案,并且您的代码严重依赖于非托管的东西,如Active Directory,我认为最好将目录搜索的逻辑从您的主应用程序域中分离出来。这是不逆风奔跑的方法。

对我来说,最好是使用外部控制台进程,将参数发送到参数字符串并捕获StandardOutput。

它会更慢,但内存不会泄漏,因为它将在控制台进程终止后由系统释放。

此外,在这种情况下,你可以不自制ad_searcher.ex,而是使用标准的dsquery等。例如:

[https://serverfault.com/questions/49405/command-line-to-list-users-in-a-windows-active-directory-group]

另一种方法是使用托管子域,但我认为这更难,我不确定所有非托管资源是否都会被释放。