So far, we have discussed some of the basics of searching, including the search root and scope. We also took a deep dive into LDAP filters. At this time, we have a few points left to cover from our original list, before we actually execute the search and examine the results.
Specifying Attribute Data to Be Returned
The DirectorySearcher class allows us to limit the attributes returned for an object found in a search. This allows us to ship significantly less data across the network than we might otherwise, and it can dramatically improve the performance of our queries.
This is done using the PropertiesToLoad property, which is a simple collection class. We use its Add and AddRange methods, as shown in Listing 4.9.
Listing 4.9. Specifying Attributes to Return
DirectorySearcher ds = new DirectorySearcher(); ds.PropertiesToLoad.Add("distinguishedName"); ds.PropertiesToLoad.Add("displayName"); //or alternately ds.PropertiesToLoad.AddRange( new string[] {"distinguishedName", "displayName"}); |
If we specify attributes that the target objects do not contain, they are simply ignored. Additionally, if we specify attributes we do not have permission to read, they are also not returned.
DirectorySearcher always loads one additional mystical property, called ADsPath, to the list, even if we do not specify anything. ADsPath is not actually an LDAP attribute, but ADSI builds this using the DN of the object returned.
Returning No Attribute Data
The DirectorySearcher also allows us to disable the retrieval of actual attribute data and instead just get the attribute names in the Result-PropertyCollection of the SearchResult object. We do this by setting the PropertyNamesOnly property to TRue. The default is false, meaning that the DirectorySearcher will retrieve the attribute names and their values.
Note: Not All Attributes May Be Returned from All Search Scopes
For the most part, we can return any attribute we want from a query, including the constructed variety. However, a few of the constructed attributes, such as tokenGroups, are available only from a base search. Attempting to return them from any other scope will result in the dreaded 0x80072020 COMException, which indicates an operations error.
In practice, we use this option infrequently, as we are typically interested in the attribute data. However, some scenarios may require knowing only which attributes are populated on a given object, or perhaps we know we will be modifying the underlying object and only want to use the GetdirectoryEntry method to get a DirectoryEntry. This option makes that easy and the search is more efficient when used.
Limiting the Number of Results to Return with the SizeLimit Property
Sometimes we want to return a single object and other times we may need to find every object in the naming context. There are valid reasons to do both, but if we want to return a limited number of objects, it is a good idea to specify how many we want to return. We do this with the SizeLimit property, as shown in Listing 4.10.
Listing 4.10. Setting the Size Limit
DirectorySearcher ds = new DirectorySearcher(); ds.SizeLimit = 2; |
A SizeLimit of zero (0, the default) indicates that we want to return the maximum number of objects allowed. If SizeLimit is greater than zero, it instructs the server to return the specified number of results instead.
Note that the server may not always honor this request. Active Directory and ADAM define a certain maximum number of objects that can be returned in a single search page, and this number cannot be exceeded, no matter how many we ask for. These limits are put in place to help protect the directory from resource exhaustion that could compromise its stability.
The other important thing to remember with the SizeLimit property is that it is honored only if we are not performing a paged search. Paged searches are discussed in detail in this chapter, in the section titled Returning Many Results with Paged Searches. Once paging is enabled, ADSI will attempt to return every object that matches the query, no matter what SizeLimit is specified.
Executing the Query and Enumerating Results |
Part I: Fundamentals
Introduction to LDAP and Active Directory
Introduction to .NET Directory Services Programming
Binding and CRUD Operations with DirectoryEntry
Searching with the DirectorySearcher
Advanced LDAP Searches
Reading and Writing LDAP Attributes
Active Directory and ADAM Schema
Security in Directory Services Programming
Introduction to the ActiveDirectory Namespace
Part II: Practical Applications
User Management
Group Management
Authentication
Part III: Appendixes
Appendix A. Three Approaches to COM Interop with ADSI
Appendix B. LDAP Tools for Programmers
Appendix C. Troubleshooting and Help
Index