We help IT Professionals succeed at work.

Autocomplete in VB.net using LDAP usernames

Medium Priority
839 Views
Last Modified: 2012-03-24
I am trying to create an auto complete textbox in VB.net using username in LDAP
I am using this in other parts of the code.

Public Shared Function GetUser(ByVal UserName As String) As DirectoryEntry
    'create an instance of the DirectoryEntry
    Dim dirEntry As DirectoryEntry = GetDirectoryObject("/" + GetLDAPDomain())

    'create instance fo the direcory searcher
    Dim dirSearch As New DirectorySearcher(dirEntry)

    dirSearch.SearchRoot = dirEntry
    'set the search filter
    dirSearch.Filter = "(&(objectCategory=user)(cn=" + UserName + "))"
    'deSearch.SearchScope = SearchScope.Subtree;

    'find the first instance
    Dim searchResults As SearchResult = dirSearch.FindOne()

    'if found then return, otherwise return Null
    If Not searchResults Is Nothing Then
        'de= new DirectoryEntry(results.Path,ADAdminUser, _
             ADAdminPassword,AuthenticationTypes.Secure);
        'if so then return the DirectoryEntry object
        Return searchResults.GetDirectoryEntry()
    Else
        Return Nothing
    End If
End Function

Open in new window

Can it be done?
Comment
Watch Question

CERTIFIED EXPERT
Most Valuable Expert 2012
Top Expert 2014

Commented:
You can remove the filter to get all users back and then use that as autocomplete source.

Author

Commented:
I removed the filter and changed the function name

In the page load
       
 Try

            ADWrapper.AutoPopulateUser(UserName)
            txtUser.AutoCompleteCustomSource.Clear()
 
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

Open in new window


How whould I add it to a loop to start
CERTIFIED EXPERT
Most Valuable Expert 2012
Top Expert 2014

Commented:
You changed it to do a FindAll instead of FindOne and used a searchresultcollection class right?

http://msdn.microsoft.com/en-us/library/system.directoryservices.directorysearcher.findall.aspx

Author

Commented:
This is what I did
 Public Shared Function AutoPopulateUser(ByVal UserName As String) As DirectoryEntry
            'create an instance of the DirectoryEntry
            Dim dirEntry As DirectoryEntry = GetDirectoryObject("/" + GetLDAPDomain())

            'create instance fo the direcory searcher
            Dim dirSearch As New DirectorySearcher(dirEntry)

            dirSearch.SearchRoot = dirEntry
            'set the search filter
            'dirSearch.Filter = "(&(objectCategory=user)(cn=" + UserName + "))"
            'deSearch.SearchScope = SearchScope.Subtree;

            'find the first instance
            Dim searchResults As SearchResultCollection = dirSearch.FindAll()

            'if found then return, otherwise return Null
            If Not searchResults Is Nothing Then
                'de= new DirectoryEntry(results.Path,ADAdminUser,ADAdminPassword,AuthenticationTypes.Secure);
                'if so then return the DirectoryEntry object
                Return searchResults.GetEnumerator()
            Else
                Return Nothing
            End If
        End Function

Open in new window

now how do I loop through it to get results?
Thank you for the help

Author

Commented:
Do I  use the on text changed for the text box and call the AutoPopulateUser and use the searchresults (Dim serachresults)in the pageload
CERTIFIED EXPERT
Most Valuable Expert 2012
Top Expert 2014

Commented:
Use the ForEach on SearchResults object to populate a list of string.

Call the function to populate the list of string on form load. Then set the textbox properties and it will take care of using the list to make suggestions or append matching names depending on your chosen mode.

Author

Commented:
so.......not getting it?
Dim results As List(Of String) = New List(Of String)
	vals.Add("???")
	vals.Add("???")
	vals.Add("???")

        Try

            ADWrapper.AutoPopulateUser(Nothing)
            Dim results = ADWrapper.AutoPopulateUser(searchResults)
            txtUser.AutoCompleteCustomSource.Clear()
            For Each s In results
                txtUser.AutoCompleteCustomSource.Add(s)

            Next

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

Open in new window

CERTIFIED EXPERT
Most Valuable Expert 2012
Top Expert 2014

Commented:
Modify your function so that it returns a list(of string). Then in function

change

            If Not searchResults Is Nothing Then
                'de= new DirectoryEntry(results.Path,ADAdminUser,ADAdminPassword,AuthenticationTypes.Secure);
                'if so then return the DirectoryEntry object
                Return searchResults.GetEnumerator()
            Else
                Return Nothing
            End If

Open in new window



to


    Dim names As New List(of String)
            If Not searchResults Is Nothing Then
               For Each result in SearchResults
                    names.Add(result.GetDirectoryEntry().Name)
               Next
            End If
     Return Names

Open in new window


Once you have this list of names, we will move to next part.

Author

Commented:
Done please see code I also had to Dim the result

       
 Public Shared Function AutoPopulateUser(ByVal UserName As String) As List(Of String)
            'Public Shared Function AutoPopulateUser() As DirectoryEntry
            'create an instance of the DirectoryEntry
            Dim dirEntry As DirectoryEntry = GetDirectoryObject("/" + GetLDAPDomain())

            'create instance fo the direcory searcher
            Dim dirSearch As New DirectorySearcher(dirEntry)

            dirSearch.SearchRoot = dirEntry
            'set the search filter
            'dirSearch.Filter = "(&(objectCategory=user)(cn=" + UserName + "))"
            'deSearch.SearchScope = SearchScope.Subtree;

            'find the first instance
            Dim searchResults As SearchResultCollection = dirSearch.FindAll()

            'if found then return, otherwise return Null
            Dim result
            Dim names As New List(Of String)
            If Not searchResults Is Nothing Then
                For Each result In searchResults
                    names.Add(result.GetDirectoryEntry().Name)
                Next
            End If
            Return names

        End Function

Open in new window

CERTIFIED EXPERT
Most Valuable Expert 2012
Top Expert 2014

Commented:
So now you successfully get a list of names?

Set the list of names as AutoCompleteSource property of the textbox. See example in below link

http://msdn.microsoft.com/en-us/library/system.windows.forms.textbox.autocompletesource.aspx

Author

Commented:
Does this look correct? - I dont know if it takes a  long time to query or if its not working
but its not doing autocomplete

       
Dim mSource As New AutoCompleteStringCollection()
        mSource.Add(ADWrapper.AutoPopulateUser(txtUser.Text).ToString())
        With txtUser
            txtUser.AutoCompleteCustomSource = mSource
            .AutoCompleteMode = AutoCompleteMode.SuggestAppend
            .AutoCompleteSource = AutoCompleteSource.CustomSource
            .Visible = True
        End With

Open in new window

Author

Commented:
Here is my updated code can anyone tell me why ADentry in Dim Ds As New List(of ADEntry) undefined?
        Try
            Dim ADEntry As New AutoCompleteStringCollection()
            Dim Ds As New List(Of ADEntry)()
            Ds = New DirectoryEntry("MYSERVER", "MYUSERNAME", "MYPASSWORD")
            Dim dt As New DataTable()
            dt.Columns.Add("Name", GetType(String))
            dt.Columns.Add("Email", GetType(String))
            For Each adentry As ADEntry In Ds
                Dim dr As DataRow = dt.NewRow()
                For i As Integer = 0 To adentry.Information.Count - 1
                    If adentry.Information(i).Key = "mail" Then
                        dr("Email") = adentry.Information(i).Value
                    End If
                    If adentry.Information(i).Key = "displayname" Then
                        dr("Name") = adentry.Information(i).Value
                    End If
                Next
                If Not dr("Email").ToString().Equals("") Then
                    dt.Rows.Add(dr)
                End If
            Next

Open in new window

Author

Commented:
Could anyone help with this - I have my function in my class it returns a List(Of string)
I am trying to auto populate it in a textbox I have - how do I assign the List(of string) from that function
My Auto complete code is
        Try
            Dim mSource As New AutoCompleteStringCollection()
            mSource.AddRange(ADWrapper.AutoPopulateUser(txtUser.Text))


            With txtUser
                txtUser.AutoCompleteCustomSource = mSource
                .AutoCompleteMode = AutoCompleteMode.SuggestAppend
                .AutoCompleteSource = AutoCompleteSource.CustomSource
                .Visible = True
            End With
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

Open in new window


my function in the class is (and this works)
       Public Shared Function AutoPopulateUser(ByVal UserName As String) As List(Of String)
            'Public Shared Function AutoPopulateUser() As DirectoryEntry
            'create an instance of the DirectoryEntry
            Dim dirEntry As DirectoryEntry = GetDirectoryObject("/" + GetLDAPDomain())

            'create instance fo the direcory searcher
            Dim dirSearch As New DirectorySearcher(dirEntry)

            dirSearch.SearchRoot = dirEntry
            'set the search filter
            'dirSearch.Filter = "(&(objectCategory=user)(cn=" + UserName + "))"
            'deSearch.SearchScope = SearchScope.Subtree;

            'find the first instance
            Dim searchResults As SearchResultCollection = dirSearch.FindAll()

            'if found then return, otherwise return Null
            Dim result
            Dim names As New List(Of String)
            If Not searchResults Is Nothing Then
                For Each result In searchResults
                    names.Add(result.GetDirectoryEntry().Name)
                Next
            End If
            Return names

Open in new window


can someone PLEASE HELP

Author

Commented:
Am I close? it keeps telling me UserName is undefined
       
 Try
            Dim mSource As New AutoCompleteStringCollection()
            Dim UserName As New List(Of String)
            Dim suggestions As List(Of String) = New List(Of String)(New String() {ADWrapper.AutoPopulateUser(Username)})


            mSource.AddRange(suggestions.ToArray)


            With txtUser
                txtUser.AutoCompleteCustomSource = mSource
                .AutoCompleteMode = AutoCompleteMode.SuggestAppend
                .AutoCompleteSource = AutoCompleteSource.CustomSource
                .Visible = True
            End With
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

Open in new window

Any help please?  would be greatly appreciatred

Author

Commented:
i found the problem with UserName now it is telling me
Value of type 'System.Collections.Generic.List(Of String)' cannot be converted to 'String'.
Any help is always appreciated

Author

Commented:
I found it - it works now
CERTIFIED EXPERT
Most Valuable Expert 2012
Top Expert 2014
Commented:
I helped you half the way didn't i?