Search code examples
vb.netvb.net-2010directoryservicesoutofrangeexceptiondirectorysearcher

DirectoryServices Search Out of Range Error


I am trying to get a full list of users along with their email address. After trying a lot of things the below has finally gave me some form of joy however I get this error this error:

A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll

Does anybody know why this is happening and how to prevent this? The full code is below.

Dim entry As DirectoryEntry = Nothing
Dim search As DirectorySearcher = Nothing
entry = New DirectoryEntry()
search = New DirectorySearcher()
search.Filter = "(&(objectCategory=person)(objectClass=user)(mail=*@companyname.com*))"
search.Sort.PropertyName = "cn"
Dim result As SearchResultCollection = search.FindAll()
For Each res As SearchResult In result
    Dim Name = res.Properties("cn")(0).ToString()
    Dim Email = res.Properties("mail")(0).ToString()
WindowsForm1.ListBox1.Items.Add(Name & " <" & Email & ">")
Next
entry.Dispose()
search.Dispose()
result.Dispose()

Solution

  • It looks like this is assuming res.Properties has the keys "cn" and "mail" with values that are arrays that have at least one element in them.

    res.Properties("cn")(0).ToString()

    This says 'convert the first element in the array from res.Properties whose key name is cn to a string.' That kind of sounds confusing because it is. And it assumes you know:

    1. res.Properties has an element whose key name is cn
    2. That element has a value that is a type of an array
    3. That array has an element in it at location 0
    4. The element at the location can be converted to a string

    Try checking these before attempting to access them. I haven't looked into any type-specific functionality but below should work.

    Dim Name, Email as String
    If Not IsNothing(res.Properties("cn")) AndAlso res.Properties("cn").Count > 0 AndAlso Not IsNothing(res.Properties("mail")) AndAlso res.Properties("mail").Count > 0 Then
    
        Name = res.Properties("cn")(0)
        Email = res.Properties("mail")(0)
    End If
    

    This should be more cleaned up but the idea and root cause is the same - we're trying to avoid accessing values of an array until we're sure we have an array that has a value to be accessed in the first place. Always validate your data.