0

I am developing a web based employee telephone directory for my organization that queries Active Directory for its data using C#/AccountManagement. I am trying to query AD and create a list of 'Employees' based on User Principals returned. I can get all records but want to be able to return paginated results from the server for performance reasons. I have tried to utilize LINQ (Take and Skip) on my FindAll() method but the problem I am running into is I further filter my results to check for empty GivenName and Surname to get rid of test accounts etc. This ends up returning for example 16 results when I try to .Take(20). This is my first attempt at using AD in an app and am hoping someone can point me in the right direction, would love any advise or critique. Below is the data access method:

public static List<Employee> GetAllEmployees()
    {
        List<Employee> employees = new List<Employee>();
        try
        {

            PrincipalContext context = new PrincipalContext(ContextType.Domain, "My Domain");

            GroupPrincipal gp = GroupPrincipal.FindByIdentity(context, "Domain Users");

            UserPrincipal principal = new UserPrincipal(context);

            principal.Enabled = true;
            using (PrincipalSearcher searcher = new PrincipalSearcher(principal))
            {
                searcher.QueryFilter = principal;
                var results = searcher.FindAll();

                foreach (UserPrincipal p in results)
                {
                    if (p.IsMemberOf(gp))
                    {
                        if (p.GivenName != null && p.Surname != null)
                        {
                            string division = string.Empty;
                            DirectoryEntry de = p.GetUnderlyingObject() as DirectoryEntry;
                            if (de.Properties.Contains("department"))
                            {
                                division = de.Properties["department"].Value.ToString();
                            }

                            var employee = new Employee(p.GivenName, p.Surname, p.DisplayName, p.EmailAddress, division);

                            employees.Add(employee);
                        };
                    }
                }

            }

        }
        catch (Exception)
        {

            throw;
        }
        return employees;
    }
bigtoasty
  • 108
  • 1
  • 1
  • 7
  • So what is your problem here? What's wrong with returning 16? – Hung Cao Mar 17 '17 at 05:06
  • http://stackoverflow.com/a/26954880/5621827 may help you – jitender Mar 17 '17 at 05:08
  • @HungCao Let's say that I have 1000 users, I would like to be able to return 10, 20, 50, 100 at a time for pagination of the results. If I do .Take(20) on the FindAll() method, my results will further be filtered for users without FirstName or LastName so maybe 16 is returned instead of 20. This isn't right but I am not sure how I go about filtering these results in an efficient manner before returning the next 20, 10, 50, whatever that I need. – bigtoasty Mar 17 '17 at 05:11

1 Answers1

0

Turns out the answer was something simple I had overlooked. I moved my filtering outside of the foreach loop. I got rid of:

if (p.IsMemberOf(gp))

and

if (p.GivenName != null && p.Surname != null)

and replaced with:

principal.GivenName = "*";
principal.IsMemberOf(gp);

before my loop. I am now able to perform .Take() on my searcher.Findall() method and receive the quick results I was expecting.

bigtoasty
  • 108
  • 1
  • 1
  • 7