Reputation: 361
I need to run a foreach
loop in DirectorySearcher.FindAll()
and get the displayname property. It seems like there are memory issues with that (referred link: Memory Leak when using DirectorySearcher.FindAll()).
My code is as follows:
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);
}
}
}
}
}
Is there any possible way to looping. I have also tried calling Dispose()
method but it doesn't work. Any help is really appreciated.
Upvotes: 0
Views: 10390
Reputation: 653
Here is a solution that I came up with for a project I'm working on that I think would work for you. My solution loops through the search results and returns the display name in a list of strings up to 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);
}
Upvotes: 2
Reputation: 941
If it's not valid solution in managed code and your code depend hard on not-managed things such Active Directory i think it's good idea to move logic of directory searching to isolate such logic from your main application domain. It's way to not run against wind.
For me - better is to use outer console process, send parameters to argument string and catch StandardOutput.
It will be slower, but memory will be not leaked because it will be freed by system after console process die.
Additionally in this case u can not to make self-made ad_searcher.ex, but use standard dsquery and so on. For example:
Another approach - usage of managed sub-domains, BUT i think it's harder and i'm not sure that all unmanaged resources will be freed.
Upvotes: 0