Click here to Skip to main content
15,347,625 members
Articles / Programming Languages / C#
Posted 7 Mar 2005


26 bookmarked

An RFC 2253 Compliant Distinguished Name Parser

Rate me:
Please Sign up or sign in to vote.
4.87/5 (9 votes)
27 Mar 2009CPOL3 min read
A set of classes to parse and manipulate LDAP distinguished names
Sample Image - DNParser.png


Every object in an LDAP directory is uniquely identified by a distinguished name (DN). A distinguished name specifies the name of the object itself, along with the names of all its parent objects. Thus, a DN identifies the object itself as well as its position in the tree.

The rules for representing distinguished names as strings are laid out in RFC 2253, and they actually get a little complex in places. Hence, this parser.


I was rewriting some terrible ADSI code (that I wrote myself a few years ago, but I'm going to gloss over that little detail), and I noticed that the original code navigated the LDAP tree by getting an ADSI object, reading its distinguishedName property, then getting its parent object and reading that object's distinguishedName property recursively. That procedure made me pretty uncomfortable because it involved a lot of back-and-forth with the server that wasn't really necessary. I figured it would be a simple thing to parse a distinguished name in code, thereby avoiding all the server-side processing. Well, it turns out that it was less simple than I expected, but it came out pretty well, so I thought I'd share the results with you folks.

Using the code

There are three main classes in this code:

  • DN, which represents a full distinguished name
  • RDN, which represents a relative distinguished name
  • RDNComponent, which represents the individual components of a multivalued RDN

I don't think that multivalued RDNs are even supported by Active Directory, but they're supported by the RFC, so they're supported by my parser.

You construct a DN object by feeding it a distinguished name string, like so:

DN myDN = new DN(@"CN=Pete Everett\, esq.,OU=People,DC=example,DC=com");

To print out a DN object, you use its ToString() method, as you'd expect.

// prints out:
// CN=Pete Everett\, esq.,OU=People,DC=example,DC=com

But if you'd like more control over the formatting, you can specify categories of characters to escape.

// prints out:
// CN=Pete Everett, esq.,OU=People,DC=example,DC=com
// (Note that this is an incorrect DN format, and will not parse correctly.)

To get the parent object of a given DN object, you can use its Parent property.

DN myParentDN = myDN.Parent;
// prints out:
// OU=People,DC=example,DC=com

And to get a child of a given DN object, you can use its GetChild() method.

DN myChildDN = myParentDN.GetChild("CN=Mike");
// prints out:
// CN=Mike,OU=Poeple,DC=example,DC=com

You can also access the individual RDNs of a given DN object, like so:

// prints out:
// DC=example

And you can get the type or value of a component of an RDN, if you're inclined.

// prints out:
// People

Design Considerations

I wanted to make sure that each DN (and its component parts) was immutable. This allowed me to do a couple of cute things up front, like calculate an object's hash code upon object creation (and use the hash code as a quick test for inequality) and pass references to the same underlying objects between different DN objects. For example:

// referenceDN contains references to 4 RDN objects
DN referenceDN = new DN("OU=Marketing,OU=People,DC=example,DC=com");
// parentDN contains references to 3 of the same RDN objects from referenceDN
DN parentDN = referenceDN.Parent;

It's worth noting, though, that this only does the job halfway, because:

// childDN is now equal to referenceDN, but its first RDN points to a
// different object than referenceDN's first RDN does.
DN childDN = parentDN.GetChild("OU=Marketing");


  • This is my first crack at coding something to match an RFC. I think I've done a pretty good job of it, but it's possible that I've misinterpreted something in the spec. Send criticisms my way. (But be gentle. I'm a little sensitive.)
  • Working with multibyte characters is tricky. The RFC specifies that multibyte characters should be allowed to be escaped as their individual bytes. So for example, Unicode character 0x266B (a musical note) should be allowed to be represented as \E2\99\AB (its three-byte UTF-8 encoding). The problem is that ADSI's GetObject() method (and anything built on top of it, like .NET's DirectoryServices stuff) doesn't support escaped multibyte characters. So if you feed it an escaped character, it'll choke. But if you feed an unescaped multibyte character to something that expects ASCII, it'll also choke. My workaround to this problem has been to let you choose which categories of characters to escape. (There's an example above.)
  • I thought up as many strange test cases as I could and wrote a bunch of NUnit tests which kept me company throughout the development process. I've included the tests along with the code, so you can verify that any changes you might want to make won't break existing functionality. I'm sure, though, that I've done a half-hearted job of thinking of tests, and if you see any glaring omissions, please send them my way.


  • March 7, 2005 - Initial posting
  • March 26, 2009 - Fixed some null-reference bugs


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


About the Author

Pete Everett
Software Developer (Senior)
United States United States
Pete has just recently become a corporate sell-out, working for a wholly-owned subsidiary of "The Man". He counter-balances his soul-crushing professional life by practicing circus acrobatics and watching Phineas and Ferb reruns. Ducky Momo is his friend.

Comments and Discussions

QuestionNew feature Pin
englebart27-Oct-17 3:42
professionalenglebart27-Oct-17 3:42 
QuestionGithub & Nuget Pin
Member 1041262321-Sep-15 23:58
MemberMember 1041262321-Sep-15 23:58 
AnswerRe: Github & Nuget Pin
Member 1041262322-Sep-15 1:37
MemberMember 1041262322-Sep-15 1:37 
QuestionInternal .NET Utility class can be called using reflection Pin
gbrayut29-Apr-14 7:04
Membergbrayut29-Apr-14 7:04 
QuestionError parsing Distinguished Names with a comma Pin
Jeremy Hutchins3-Oct-13 9:50
MemberJeremy Hutchins3-Oct-13 9:50 
QuestionGithub and updates Pin
Member 95767538-Nov-12 9:19
MemberMember 95767538-Nov-12 9:19 
QuestionRFC compliance and .Net Pin
Alan Seedhouse16-Apr-12 23:49
professionalAlan Seedhouse16-Apr-12 23:49 
GeneralUnable to Parse names with / Pin
CoderGirl4225-Mar-09 13:42
MemberCoderGirl4225-Mar-09 13:42 
AnswerRe: Unable to Parse names with / Pin
Pete Everett26-Mar-09 8:10
MemberPete Everett26-Mar-09 8:10 
QuestionBug? Pin
CoderGirl4218-Mar-09 9:17
MemberCoderGirl4218-Mar-09 9:17 
AnswerRe: Bug? Pin
Pete Everett26-Mar-09 5:18
MemberPete Everett26-Mar-09 5:18 
AnswerRe: Bug? Pin
Pete Everett27-Mar-09 10:12
MemberPete Everett27-Mar-09 10:12 
GeneralGood work! [modified] Pin
CoderGirl4214-Mar-09 10:11
MemberCoderGirl4214-Mar-09 10:11 
QuestionPermission to ingegrate in another project Pin
Roman Rozinov15-Dec-08 20:10
MemberRoman Rozinov15-Dec-08 20:10 
AnswerRe: Permission to ingegrate in another project Pin
Pete Everett17-Dec-08 1:21
MemberPete Everett17-Dec-08 1:21 
GeneralRe: Permission to ingegrate in another project Pin
Roman Rozinov17-Dec-08 7:38
MemberRoman Rozinov17-Dec-08 7:38 
GeneralYou rock! Pin
Mikeoff15-Nov-06 0:57
MemberMikeoff15-Nov-06 0:57 

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.