How to get user names and surnames and show them in ASP.NET MVC 4 autocomplete?

Today I was working on some autocompletion with users (name + surname) from Active Directory (from now on AD) in ASP.NET MVC 4 application. I wanted to get suggestions on the fly based on user’s input. I was accessing AD using Lightweight Directory Access Protocol (from now on LDAP).

You have to add two references into your project: System.DirectoryServices.dll and System.DirectoryServices.AccountManagement.dll. In your class you have to use two namespaces:

using System.DirectoryServices.AccountManagement;
using System.DirectoryServices;
In your controller you do something like this:
public JsonResult AutocompleteUsers(string term)
{
    string filter = "(&(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))(|(givenName={0}*)(sn={1}*)))";
    List persons = new List();

    DirectoryEntry dE = new DirectoryEntry(); //initialization
    {
        //uniquely identifies entry in a networked environment
        dE.Path = "directory entry path"; 

        //username for client authentication
        dE.Username = "directory entry username"; 
        
        //password for client authentication
        dE.Password = "directory entry password";

        //authentication types
        dE.AuthenticationType = AuthenticationTypes.ServerBind; 
    }
    
    DirectorySearcher dS = new DirectorySearcher(dE); //applying search filter
    {
        dS.Filter = String.Format(filter, term, term);
    }

    foreach (SearchResult result in dS.FindAll())
    {
        if (result != null)
        {
            DirectoryEntry entry = result.GetDirectoryEntry();
            
            string name = (entry.Properties["givenName"].Value ?? "").ToString();
            string surname = (entry.Properties["sn"].Value ?? "").ToString();

            if (!String.IsNullOrEmpty(name) && !String.IsNullOrEmpty(surname)) 
            {
                persons.Add(name + " " + surname);
            }
        }
    }

    IEnumerable ipersons = persons.AsEnumerable().OrderBy(p => p);

    return this.Json(ipersons, JsonRequestBehavior.AllowGet);
}
So, firstly you initialize connection with AD. After that you apply search filter. Part (objectCategory=person) returns user and contact objects. Because we only want users, we also need part (!userAccountControl:1.2.840.113556.1.4.803:=2). Contacts don’t have userAccountControl attribute, so this part will always be True for them. With part (objectClass=user) we restrict query to just user object. Part (|(givenName={0}*)(sn={1}*))) restricts query on users which name or surname starts with specified string. After that we loop through search results and get the names.
Collection of names is returned as Json. We must allow get with option JsonRequestBehavior.AllowGet. By default “Json get” is not allowed and without mentioned option exception is produced (Internal Server Error).On client site we have to attach following JavaScript code:

$(document).ready(function () {
    $('#textbox_id').autocomplete({
	source: '@Url.Action("action_name", "controller_name")'
    });
});
Textbox value (inserted string) is automaticaly sent in query string as parameter term. We must not forget to import jQuery scripts:
@Styles.Render("~/Content/themes/base/css")
@Scripts.Render("~/bundles/jquery")    
@Scripts.Render("~/bundles/jqueryui")

Without that callback won’t happen. 🙂