views:

134

answers:

6

I'm using C# to write a simple program to read Active Directory and display the value held in a AD field on a Windows form program.

If a property doesn't exist then the program crashes, below is my code, how can I catch this and move on to the next field without doing a try/catch for each and every attribute?

DirectoryEntry usr = new DirectoryEntry("LDAP://" + domain, username, password);
DirectorySearcher searcher = new DirectorySearcher(usr);
searcher.Filter = "(sAMAccountName=" + GlobalClass.strUserName + ")";
searcher.CacheResults = false;
searcher.SearchScope = SearchScope.Subtree;
searcher.PropertiesToLoad.Add("givenName");
searcher.PropertiesToLoad.Add("telephoneNumber");

//program crashes here if telephoneNumber attribute doesn't exist.
textBoxFirstName.Text = usr.Properties["telephoneNumber"].Value.ToString();
+7  A: 

Just checking usr.Properties["telephoneNumber"] will not work. You must check the actual value. The reason the error is occuring is because you're calling ToString() on Value which is null.

user.Properties will always return a PropertyValueCollection, regardless of the property name entered into the collections indexer.

I.e.

var pony = usr.Properties["OMG_PONIES"]; // Will return a PropertyValueCollection
var value = pony.Value;                  // Will return null and not error

You need to check the value itself, the best way through the null coalescing operator:

textBoxFirstName.Text = (usr.Properties["telephoneNumber"].Value 
                            ?? "Not found").ToString();
GenericTypeTea
But won't that fail if `usr.Properties["telephoneNumber"]` is `null`?
Jim Mischel
@Jim Mischel - No. It's never null. Look at my `usr.Properties["OMG_PONIES"]` example. I thought the same as the rest of the answers until I tested it myself. You can sit typing `Properties["RAR_FOO_DOH"]` and it'll never return null.
GenericTypeTea
+1, I didn't think to check if usr.Properties[] would actually return null.
Brandon
@Generic: Ahhh, I see. It returns an empty collection if the property doesn't exist. I need to wake up. You said that explicitly in your response.
Jim Mischel
@Brandon - I made the same mistake. See my first revision :).
GenericTypeTea
+2  A: 

Use the null-coalescing operator (??) operator.

textBoxFirstName.Text = (usr.Properties["telephoneNumber"].Value 
                            ?? String.Empty).ToString();

This way the value is replaced with an empty string if null. You could also just return null instead of String.Empty, the reason your code is crashing is because you're trying to call ToString() on a null value.

Andrew Koester
@Brandon You're right, I'll edit my answer.
Andrew Koester
@Andrew, nevermind, apparently I'm wrong. See GenericTypeTea's answer.
Brandon
+1  A: 

Something like this should work. If telephoneNumber is not null, it will convert the value to a string, otherwise it will use an empty string.

textBoxFirstName.Text = usr.Properties["telephoneNumber"].Value != null 
        ? usr.Properties["telephoneNumber"].Value.ToString()
        : "";
Brandon
+3  A: 

Store the contents of usr.Properties["telephoneNumber"]; in a variable and check for null:

PropertyValueCollection tel = usr.Properties["telephoneNumber"];

textBoxFirstName.Text = (tel != null && tel.Value != null)
                      ? tel.Value.ToString()
                      : "";
dtb
I think this is the best answer of the bunch, because it doesn't index Properties twice, I have no idea how cheap that is though.
Sander Rijken
A: 
if (usr.Properties["telephoneNumber"] != null)
    textBoxFirstName.Text = usr.Properties["telephoneNumber"].Value.ToString();
BlueCode
A: 

A couple of things will help this be more graceful:

  • Test usr.Properties["telephoneNumber"] for null before calling child properties like Value. I haven't worked with AD myself, but most string-keyed indexers are designed to gracefully handle non-existent keys. the CLR, on the other hand, will happily throw a NullReferenceException any time you try to reference a member of anything that evaluates to null.

  • On the off chance that AD DOES blow up on a nonexistent column, enclose the assignment in a Try-Catch block that will show an error on the screen and gracefully continue processing (or not).

KeithS
Try-Catch blocks for NullReferenceExceptions are a bad idea 99.99% of the time..
Sander Rijken
@Sander: if usr.Properties[] is throwing it (unlikely but possible), there's not much else he can do, unless the dictionary provides a safe method to check for column existence like a ContainsColumn() method.
KeithS
ah I see what you mean, but I'm quite sure it doesn't behave like that, and that .Value is what causes the null ref.
Sander Rijken