C#从Active Directory用户填充组合框

时间:2012-09-19 19:07:14

标签: c# active-directory

我使用此代码用Active Directory用户填充组合框,但我不时会在代码工作的'for each'处获得COM异常。

System.DirectoryServices.DirectoryEntry entry = new System.DirectoryServices.DirectoryEntry("LDAP://DC=DOMAIN, DC=local");
System.DirectoryServices.DirectorySearcher mySearcher = new System.DirectoryServices.DirectorySearcher(entry);
mySearcher.Filter = "(&(objectClass=user)(objectCategory=person))";

foreach (System.DirectoryServices.SearchResult resEnt in mySearcher.FindAll())
{
   try
   {
       //DirectoryEntry de = new DirectoryEntry(resEnt.GetDirectoryEntry());
       System.DirectoryServices.DirectoryEntry de = resEnt.GetDirectoryEntry();
       comboBox2.Items.Add(de.Properties["GivenName"].Value.ToString() + " " + de.Properties["sn"].Value.ToString() + " " + "[" + de.Properties["sAMAccountName"].Value.ToString() + "]");
   }
   catch (Exception e)
   {
       // MessageBox.Show(e.ToString());
   }
}

有更有效的方法来解决错误吗?

2 个答案:

答案 0 :(得分:4)

我要做的第一件事就是将您想要从结果中抓取的属性包含在搜索结果中 - 这样,您就不必对每个结果进行.GetDirectoryEntry()调用:

using System.DirectoryServices;

DirectoryEntry entry = new DirectoryEntry("LDAP://DC=DOMAIN, DC=local");

DirectorySearcher mySearcher = new DirectorySearcher(entry);
mySearcher.Filter = "(&(objectClass=user)(objectCategory=person))";

// define the properties you want to be loaded into the search result object
mySearcher.PropertiesToLoad.Add("GivenName");
mySearcher.PropertiesToLoad.Add("samAccountName");
mySearcher.PropertiesToLoad.Add("sn");

foreach (SearchResult resEnt in mySearcher.FindAll())
{
   try
   {
       string givenName = "";
       string samAccountName = "";
       string surName = "";

       // check if you got a value - not all properties have to be filled - 
       // and if they're not filled, they might be "null". 
       if(resEnt.Properties["GivenName"] != null && 
          resEnt.Properties["GivenName"].Count > 0) 
       {
           givenName = resEnt.Properties["GivenName"].Value;
       }

       // samAccountName is a *must* property - it has to be set.
       samAccountName = resEnt.Properties["samAccountName"].Value;

       if(resEnt.Properties["sn"] != null && 
          resEnt.Properties["sn"].Count > 0) 
       {
           surName = resEnt.Properties["sn"].Value;
       }

       comboBox2.Items.Add(givenName + " " + surName + " " + "[" + samAccountName + "]");
   }
   catch (Exception e)
   {
       // MessageBox.Show(e.ToString());
   }
}

第二点是:如果您使用的是.NET 3.5或更高版本,则可以使用PrincipalSearcher和“按示例查询”主体进行搜索;此外,使用UserPrincipal对象处理结果集要容易得多,因为GivenNameSurname等内容在UserPrincipal上显示为属性:

// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// define a "query-by-example" principal - here, we search for any UserPrincipal 
UserPrincipal qbeUser = new UserPrincipal(ctx);

// create your principal searcher passing in the QBE principal    
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);

// find all matches
foreach(var found in srch.FindAll())
{
    // do whatever here 
    UserPrincipal foundUser = found as UserPrincipal;

    if(foundUser != null)
    {
       comboBox2.Items.Add(foundUser.GivenName + " " + foundUser.Surname + " " + "[" + foundUser.SamAccountName + "]");
    }
}

如果您还没有 - 绝对阅读MSDN文章Managing Directory Security Principals in the .NET Framework 3.5,该文章很好地展示了如何充分利用System.DirectoryServices.AccountManagement中的新功能。或者查看MSDN documentation on the System.DirectoryServices.AccountManagement命名空间。

当然,根据您的需要,您可能希望在您创建的“按示例查询”用户主体上指定其他属性:

  • DisplayName(通常:名字+空格+姓氏)
  • SAM Account Name - 您的Windows / AD帐户名称
  • User Principal Name - 您的“username@yourcompany.com”样式名称

您可以在UserPrincipal上指定任何属性,并将其用作PrincipalSearcher的“按示例查询”。

答案 1 :(得分:0)

将foreach循环放在try ... catch语句的catch块中。