0

I am geting an index out of bounds error, I understand why I am getting it. What I am looking for is perhaps some features of c# I may not be aware of instead of using a bulky if/else statement.

If the Active Directory user does not have a job title this errors out because it will not load the property so rs.Propterties["title"] doesn't even exist to my knowledge.

Is there a cleaner way to do it than if (rs.Properties["title"].Count)

user.jobTitle = rs.Properties["title"][0].ToString();

I was looking into different operators like ?? and ?: but couldn't figure out how to get them to work properly.

rs.Properties is of type SearchResult from:

using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.DirectoryServices.AccountManagement;

2
  • @PrestonGuillot rs is a SearchResult type. from the DirectoryServices. Commented Jun 11, 2013 at 22:23
  • Properties is typeof Dic<string, list> ? Commented Jun 11, 2013 at 22:29

3 Answers 3

3

How about:

user.jobTitle = (rs.Properties["title"].FirstOrDefault() ?? "").ToString();

That's assuming rs.Properties["title"] is of type IEnumerable<object> or something similar. If it's just IEnumerable, you'd need something like:

user.jobTitle = (rs.Properties["title"]
                   .Cast<object>()
                   .FirstOrDefault() ?? "").ToString();

The FirstOrDefault call will return null if the collection is empty.

(Now that we know the type of rs, it looks like the latter is required.)

You may want to wrap that into your own extension method, of course:

public static string GetFirstProperty(this SearchResult result,
                                      string propertyName,
                                      string defaultValue)
{
    return result.Properties[propertyName]
                 .Cast<object>()
                 .FirstOrDefault() ?? defaultValue).ToString();
}
Sign up to request clarification or add additional context in comments.

Comments

2

Option 1

user.jobTitle = rs.Properties.Contains("Title") ? rs.Properties["Title"][0].ToString() : string.Empty;

Option 2

public static class SearchResultHelper
{
    public static string GetValue(this SearchResult searchResult, string propertyName)
    {
        return searchResult.Properties.Contains(propertyName) ? searchResult.Properties[propertyName][0].ToString() : string.Empty;
    }
}

Call would look like

user.JobTitle = rs.Properties.GetValue("Title")

Thanks to http://www.codeproject.com/KB/system/getuserfrmactdircsharp.aspx for AD example

Comments

1

Is this what you're looking for?

user.jobTitle = rs.Properties["title"]
    .Cast<object>()
    .FirstOrDefault()
    .MaybePipe(x => x.ToString());

Helper function that I use everywhere:

public static TResult MaybePipe(this T obj, Func<T, TResult> func)
{
    return obj != null ? func(obj) : default(T);
}

4 Comments

Sorry I forgot to include the type which is a SearchResult type. Which doesn't have the FirstOrDefault built in. Anyone to still do it?
@JamesWilson What is the type of Properties["title"]?
It is SearchResult, updated the original post as well. Jon Skeet was able to answer it similar to your suggestions.
@JamesWilson I added the Cast<object>() call which will turn your IEnumerable into IEnumerable<object>.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.