Search code examples
c#ldapdirectoryservices

C# using DirectoryVirtualListView to page ldap query results


I am trying to get users from an LDAP server. The server is limited to 200 results per response, an I want to get all the users which are over 5000. So I need to do some kind of pagination. until now I have tried two approaches:

  1. Setting DirectorySearcher PageSize property. This approaches throws an exception that says "[DSA]:Pagging not possible when chaining (DSP) is required". Here is the code
DirectoryEntry rootEntry = new DirectoryEntry("LDAP://server.name");
rootEntry.Username = "cn=any,o=any,dc=any,dc=any";
rootEntry.Password = "thepassword";
rootEntry.AuthenticationType = AuthenticationTypes.FastBind; 
using (DirectorySearcher searcher = new DirectorySearcher(rootEntry))
{
    searcher.PageSize = 50;
    searcher.Filter = "(&(objectClass=person))";
    foreach (SearchResult sr in searcher.FindAll())
    {
        Console.WriteLine(sr.Path);
    }
}
  1. Using VirtualListView. This also throws an exception "VirtualListView property value cannot be set", and the code:
DirectoryEntry rootEntry = new DirectoryEntry("LDAP://server.name", "cn=any,o=any,dc=any,dc=any", "any", AuthenticationTypes.FastBind);
using (DirectorySearcher searcher = new DirectorySearcher(rootEntry))
{
    searcher.Filter = "(&(objectClass=person))";
    searcher.Sort = new SortOption("cn", SortDirection.Ascending);
    searcher.VirtualListView = new DirectoryVirtualListView(25);

    foreach (SearchResult sr in searcher.FindAll())
    {
        Console.WriteLine(sr.Path);
    }
}

Can anyone tell me what I am doing wrong?. thanks in advance.


Solution

  • using (var directoryEntry = new DirectoryEntry(@"LDAP://TestDomain")
    {
        Username = @"TestDomain\TestUser",
        Password = "T@st#1"
    })
    {
        var directorySearcher = new DirectorySearcher(directoryEntry)
        {
            VirtualListView = new DirectoryVirtualListView(0, 9, 1)
        };
    
        // will give you only users with mail
        var filter = "(&(objectCategory=person)(objectClass=user)(mail=*))";
    
        directorySearcher.Filter = filter;
        directorySearcher.Sort = new SortOption() { PropertyName = "displayname", 
                                                     Direction = SortDirection.Ascending };
    
        directorySearcher.PropertiesToLoad.Add("displayname");
        directorySearcher.PropertiesToLoad.Add("mail");
        directorySearcher.SearchScope = System.DirectoryServices.SearchScope.Subtree;
        directorySearcher.SizeLimit = 100;
    
        var results = directorySearcher.FindAll();
        var names = new List<string>();
    
        foreach (SearchResult r in results)
        {
            // Map the result 
        }
    }
    

    You'll have to play with and by default it sort users by cn

    1. VirtualListView = new DirectoryVirtualListView(0, 9, 1)
    2. VirtualListView = new DirectoryVirtualListView(0, 49, 100);
    
    1. It'll give you 10 records starting from 0 to 9
    2. Will get 50 users starting from the 100.