Search code examples
c#ldapdispose

How to properly dispose objects created for Ldap search using ADODB ADsDSObject provider


I am looking for the best way how to lookup LDAP directory for users by given criteria. At the moment the best performance seems to offer usage of ADsDSObject provider. The code will run in ASP.NET web site.

I would like to confirm how to properly dispose the resources. Here is the code used at the moment. Is the code releasing resources correctly or need to be improved?

public static List<LookupValues> FindBy(LdapSearchCriteria criteria)
{
    List<LookupValues> usersMatchingCriteria = new List<LookupValues>();

    ADODB.Command adoCommand = new ADODB.Command();
    ADODB.Connection adoConnection = new ADODB.Connection();
    ADODB.Recordset adoResultSet = new ADODB.Recordset();

    adoConnection.ConnectionString = connectionString;
    adoConnection.Open();
    adoCommand.ActiveConnection = adoConnection;
    adoCommand.CommandText = BuildSelectStatmentFrom(criteria);
    object dummy = Type.Missing;

    try
    {
        adoResultSet = adoCommand.Execute(out dummy, ref dummy, 0);
        if (adoResultSet != null)
        {
            while (adoResultSet.EOF == false)
            {
                LookupValues value = new LookupValues();
                for (int i = 0; i < adoResultSet.Fields.Count; i++)
                {
                    switch (adoResultSet.Fields[i].Name)
                    {
                        case "a-foreignGivenName":
                            value.FirstName = (adoResultSet.Fields[i].Value).ToString();
                            break;
                        case "a-foreignSn":
                            value.LastName = (adoResultSet.Fields[i].Value).ToString();
                            break;
                    }
                }
                usersMatchingCriteria.Add(value);
                adoResultSet.MoveNext();
            }
        }
    }
    finally
    {
        if (adoResultSet != null)
        {
            adoResultSet.Close();
            adoResultSet = null;
        }

        if (adoConnection != null)
        {
            adoConnection.Close();
            adoConnection = null;
        }
    }

    return usersMatchingCriteria;
}

Solution

  • I found equivalent and even a bit faster to use classes from System.DirectoryServices.Protocols namespace. Equivalent code using .NET classes

    public List<LookupValues> FindBy(LdapSearchCriteria criteria)
    {
        List<LookupValues> usersMatchingCriteria = new List<LookupValues>();
    
        NetworkCredential credentials = new NetworkCredential(connectionDetails.UserName, connectionDetails.Password, connectionDetails.Domain);
        LdapDirectoryIdentifier directoryIdentifier = new LdapDirectoryIdentifier(connectionDetails.Server, connectionDetails.Port, false, false);
    
        using (LdapConnection connection = CreateConnection(directoryIdentifier))
        {
            connection.Bind(credentials);
    
            SearchRequest search = CreateSearchRequest(criteria);
    
            SearchResponse response = connection.SendRequest(search) as SearchResponse;
            foreach (SearchResultEntry entry in response.Entries)
            {
                LookupValues foundUser = GetUserDetailsFrom(entry);
                usersMatchingCriteria.Add(foundUser);
            }
        }
    
        return usersMatchingCriteria;
    }