Click here to Skip to main content
15,868,141 members
Articles / Programming Languages / C#
Article

Typed LDAP Queries

Rate me:
Please Sign up or sign in to vote.
4.72/5 (9 votes)
12 Nov 2008CPOL2 min read 26.4K   282   18   3
Dynamically generating well formed LDAP queries using managed code.

Introduction

Writing queries using Lightweight Directory Access Protocol (LDAP) has always been challenging, especially when you are not used to the LDAP syntax. The inclusion of the System.DirectoryServices namespaces in the .NET framework made writing code for LDAP libraries a lot easier than with the traditional Active Directory Services Interfaces (ADSI) in non-managed languages. However, search functions in this namespaces such as the DirectorySearcher class still relies on the ability of the programmer to write LDAP queries properly, thus leaving the fate of a well formatted query on the hands of the runtime.

A More Structured Solution

After analyzing and looking for a more structured way of writing these types of queries, I found a very compelling and clever way of writing function statements with conditional logic, which I found in Microsoft Excel. Excel’s way of writing functions consists of defining the logical operator as the function and the members inside the function on which they operate. For instance, consider the following query:

SQL
Select car from cars where (car.color = colors.red OR car.color = colors.blue) 
  AND car.make = makes.ford AND car.passengers > 5 AND car.model >= 2008

It can be also expressed as:

SQL
AND(
   OR(
      EQUALTO(car.color, colors.red), 
      EQUALTO(car.color, colors.blue)), 
   EQUALTO(car.make, makes.ford), 
   GREATHERTHAN(car.passengers, 5), 
   OR(
      GREATHERTHAN(car.model, 2008),
      EQUALTO (car.model, 2008))

In LDAP, the query would be as follows:

(&( |((color=red)(color=blue))(make=ford)(passengers>5)(model>=2008) ))

You can see how similar the last two expressions are.

Search Criteria

The first thing we need is a helper class to define expressions using syntax like the above. The SearchCriteria class easily allows to define queries of this type, as defined below:

C#
public class SearchCriteria
{
   public SearchCriteria<T>[] Criteria { get; set; }
   public static AndCriteria And(params SearchCriteria<T>[] criteria)
   public static OrCriteria Or(params SearchCriteria<T>[] criteria)
   public static NotCriteria Not(SearchCriteria<T> criteria)
   public static GreatherThanFunctionCriteria GreatherThan(T name, string value)
   public static LessThanFunctionCriteria LessThan(T name, string value)
   public static EqualToFunctionCriteria EqualTo(T name, string value)
   public static ContainsFunctionCriteria Contains(T name, string value)
   public static IsLikeFunctionCriteria IsLike(T name, string value)
}

Then, to define the car query from the example above, we have to define an enumeration for fields allowed for the element car, as follows:

C#
public enum Car { color, make, passengers, model, } 

Typed LDAP

Here is how we express the query in managed code:

C#
var expression = SearchCriteria<Car>.And( 
   SearchCriteria<Car>.Or( 
      SearchCriteria<Car>.EqualTo(Car.color, Colors.red.ToString()), 
      SearchCriteria<Car>.EqualTo(Car.color, Colors.blue.ToString())), 
   SearchCriteria<Car>.EqualTo(Car.make, Makes.ford.ToString()), 
   SearchCriteria<Car>.GreatherThan(Car.passengers, "5"), 
   SearchCriteria<Car>.Or( 
      SearchCriteria<Car>.GreatherThan(Car.model, "2008"),  
      SearchCriteria<Car>.EqualTo(Car.model, "2008")));

Once we have a criteria object, we can pass that to the LdapBuilder engine, which is another static class with one method:

C#
public static string GetLdap(SearchCriteria criteria)
...
string ldapQuery = LdapBuilder<Car>.GetLdap(expression);

Then, invoking this method will dynamically call the proper routines that will generate a string representing a well formed LDAP query, that simple!

The Sample Code

In the sample code, you will find a fully functional version of this engine along with the implementation of the car example used in this article. Enjoy it :)

TypedLdapTestForm.jpg

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Born and built for Software Development. Eager to develop systems that drive business and human intelligence to the next level. Love Artificial Intelligence and have abundant experience in developing systems with a large user base. I know more than just how to write code that compiles. I can produce software that is fast, reliable, well-tested, secure, maintainable, globalizable, and on down the list of attributes of high-quality code.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Amir Mohammad Nasrollahi7-Aug-13 22:12
professionalAmir Mohammad Nasrollahi7-Aug-13 22:12 
GeneralLDAP Criteria Pin
oaam19-Nov-08 7:18
oaam19-Nov-08 7:18 
GeneralExcellent idea Pin
rht34116-Nov-08 4:19
rht34116-Nov-08 4:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.