Before I go on with the code, I'd figure I'd mention this. Some of my code is now over at CodePlex... Well, not my direct code, more like a modified version. I had an email from someone who wanted to use my AES encryption code in their project (which can be found here). As always, I said it was fine. The reason I mention this is two fold:
- Hopefully someone will read this, click on the link to his project and find it helpful as it does seem promising.
- Any bits of code I put up here are free to use. All I ask is that you link back to my site and give me some sort of credit.
Anyway, I really hope that the project works out. And definitely check it out... Now on with the code.
Many companies out there are using Active Directory. For anyone creating, or working on, a company intranet site, this can be a great boon as well as rather annoying sometimes. With ASP.Net, it's incredibly easy to set up the providers to use AD or (if you really need to) create your own providers to access it. That really isn't an issue. However, inevitably you're going to have someone ask for a bit more integration.
In my case, I had someone who wanted to do a directory search of their employees that pulled the information from AD. This is actually pretty simple to do and as always, I'm here to show you the code:
1: public static List<ADEntry> GetEntry(string UserName, string Password, string SearchString)
2: {
3: try
4: {
5: List<ADEntry> ReturnValue = new List<ADEntry>();
6: DirectoryEntry deDirEntry = new DirectoryEntry("LDAP://SERVERNAME",
7: UserName,
8: Password,
9: AuthenticationTypes.Secure);
10: DirectorySearcher mySearcher = new DirectorySearcher(deDirEntry);
11: mySearcher.PropertiesToLoad.Add("mail");
12: mySearcher.PropertiesToLoad.Add("title");
13: mySearcher.PropertiesToLoad.Add("displayname");
14: mySearcher.PropertiesToLoad.Add("department");
15: mySearcher.PropertiesToLoad.Add("telephonenumber");
16:
17: string sFilter = String.Format("(&(objectcategory=user)(|(givenname=" + SearchString + "*)(sn=" + SearchString + "*)))");
18:
19: mySearcher.Filter = sFilter;
20: mySearcher.Sort.Direction = SortDirection.Ascending;
21: mySearcher.Sort.PropertyName = "cn";
22: mySearcher.PageSize = 1000;
23:
24: SearchResultCollection Results;
25:
26: Results = mySearcher.FindAll();
27:
28: foreach (SearchResult Result in Results)
29: {
30: ResultPropertyCollection Properties = Result.Properties;
31: ADEntry Entry=new ADEntry();
32: foreach (string Key in Properties.PropertyNames)
33: {
34: foreach (object Values in Properties[Key])
35: {
36: Entry.AddItem(Key, Values.ToString());
37: }
38: }
39: ReturnValue.Add(Entry);
40: }
41: return ReturnValue;
42: }
43: catch
44: {
45: return null;
46: }
47: }
The code above does a couple of things. First, it connects to the AD server (which you'll have to specify). After that, it asks the server to only return mail (email address), title (the person's title), displayname (the person's name, you could specify givenname, first name, and sn, last name, instead if you'd like), department (person's department), and telephonenumber (person's phone number/extension, depends on how it's set up). After that, it sets up the actual query. In this case the query is asking for all users who have either a last name or first name that starts with the query string. We then set the sorting and also the page size (if that isn't set we'll only get at max 1000 items returned). Finally we actually do the search and return the values.
There is one thing that I need to point out though, the code above is using a class called ADEntry. This is a simple helper class that I've created for returning information (it's similar to a StringDictionary but allows multiple entries). Anyway, it would probably be helpful if I showed that code as well, so here you go:
1: /// <summary>
2: /// An individual AD Entry
3: /// </summary>
4: public class ADEntry
5: {
6: #region Constructor
7: /// <summary>
8: /// Constructor
9: /// </summary>
10: public ADEntry()
11: {
12: _Information = new List<ADPair>();
13: }
14: #endregion
15:
16: #region Private Variables
17: private List<ADPair> _Information=null;
18: #endregion
19:
20: #region Public Properties
21: /// <summary>
22: /// Information for this AD Entry
23: /// </summary>
24: public List<ADPair> Information
25: {
26: get { return _Information; }
27: set { _Information = value; }
28: }
29: #endregion
30:
31: #region Public Functions
32: /// <summary>
33: /// Adds an item to the entry
34: /// </summary>
35: /// <param name="Name">Name of the information</param>
36: /// <param name="Value">Value of the entry</param>
37: public void AddItem(string Name,string Value)
38: {
39: ADPair Item=new ADPair();
40: Item.Key=Name;
41: Item.Value=Value;
42: Information.Add(Item);
43: }
44: #endregion
45: }
46:
47: /// <summary>
48: /// AD item pair
49: /// </summary>
50: public class ADPair
51: {
52: #region Private Variables
53: private string _Key="";
54: private string _Value="";
55: #endregion
56:
57: #region Public Properties
58: /// <summary>
59: /// Key for the pair
60: /// </summary>
61: public string Key
62: {
63: get { return _Key; }
64: set { _Key = value; }
65: }
66:
67: /// <summary>
68: /// Actual value of the pair
69: /// </summary>
70: public string Value
71: {
72: get { return _Value; }
73: set { _Value = value; }
74: }
75: #endregion
76: }
It's actually two classes, the entry and another class which is simply holds a key/value pair (the key being the items name, displayname, mail, etc., and value being the actual information). It's basic, I know but it does the job. But that's all there is to the code. I'd probably create a business object to parse the info sent back, but other than that it's pretty much ready to go. So try out the code, leave feedback, and happy coding.