If You are developer and You have to utilize Active Directory or ADAM in Your application .NET System.DirectoryServices (S.DS) namespace is nice thing to have. It simplifies operation performed against Active Directory, hiding all COM stuff behind relatively few different classes You can use to query and modify directory objects.
S.DS is nice namespace, but it still utilizes COM objects (ADSI) which are placed underneath this model. In most cases this is not a problem, but when it comes to troubleshooting something or Your application is receiving COM exceptions – this really make Your life painful, and You can't make anything about it (almost) as this is behind Your reach.
Lately one of my colleagues was working on relatively simple application which was querying Active Directory for some data. Nice and easy … build Your filter, query AD, return results. With S.DS such app can be build in few hours with tests. But when this application was tested in customer environment some COM exception started to occur. This application was using DirectorySearcher to find objects, and then it was enumerating results with foreach statement. From time to time, after calling .FindAll() following exception was raised:
System.DirectoryServices.DirectoryServicesCOMException (0x800700EA): More data is available.
After some work being done in the lab we were able to figure out that this occurs only when AD was under some load – in tests we used admod to produce load on our virtual machine and then we were able to reproduce this error.
We found KB 833879 which described such situation with .NET 1.1 , our app was built using .NET 2.0. After few e-mail we were able to confirm that this KB applies to .NET 2.0 as well, and workaround showed in this KB should work for our app as well. We have tested it and it showed up to be correct. Only thing which has to be updated was version in app configuration file (described in KB 833879), from:
This solved problem with COM exception being raised on search results enumerations.
Other way to solve this problem is to use System.DirectoryServices.Protocols (S.DS.P) to perform such search operation. Excellent example on how to do this is provided on Ray Dunn blog. S.DS.P is using directly Win32 LDAP API to communicate with directory, which is faster (no ADSI layer in the middle) and let avoid such problems with COM exceptions.
If I'm writing about programming for directory services in .NET, I want to recommend to everyone interested in this topic excellent book The .NET Developer's Guide to Directory Services Programming by Ray Dunn and Joe Kaplan. It is "must to have" book for every beginner and "nice to have" for more experienced developers.
I've decided to describe this issue here as I found at least few cases on groups where somebody was struggling with this case in .NET 2.0. Now we have workaround and solution.
Credits for hunting and testing this goes to Czarek Nolewajka, my friend from times when I lived back in Wroclaw, and now my MCS buddy :).