【问题标题】:How do I loop through a PropertyCollection如何循环通过 PropertyCollection
【发布时间】:2009-03-12 22:46:25
【问题描述】:

谁能提供一个如何循环 System.DirectoryServices.PropertyCollection 并输出属性名称和值的示例?

我正在使用 C#。

@JaredPar - PropertyCollection 没有名称/值属性。它确实有一个 PropertyNames 和 Values,类型为 System.Collection.ICollection。我不知道构成 PropertyCollection 对象的基线对象类型。

再次@JaredPar - 我最初用错误的类型错误地标记了问题。那是我的错。

更新:根据 Zhaph - Ben Duguid 的输入,我能够开发以下代码。

using System.Collections;
using System.DirectoryServices;

public void DisplayValue(DirectoryEntry de)
{
    if(de.Children != null)
    {
        foreach(DirectoryEntry child in de.Children)
        {
            PropertyCollection pc = child.Properties;
            IDictionaryEnumerator ide = pc.GetEnumerator();
            ide.Reset();
            while(ide.MoveNext())
            {
                PropertyValueCollection pvc = ide.Entry.Value as PropertyValueCollection;

                Console.WriteLine(string.Format("Name: {0}", ide.Entry.Key.ToString()));
                Console.WriteLine(string.Format("Value: {0}", pvc.Value));                
            }
        }      
    }  
}

【问题讨论】:

    标签: c# asp.net iis directoryservices


    【解决方案1】:

    在运行时在监视窗口中查看 PropertyValueCollection 的值以识别元素的类型,它包含&您可以扩展它以进一步查看每个元素具有的属性。

    添加到@JaredPar 的代码

    PropertyCollection collection = GetTheCollection(); foreach ( PropertyValueCollection value in collection ) { // Do something with the value Console.WriteLine(value.PropertyName); Console.WriteLine(value.Value); Console.WriteLine(value.Count); }

    编辑:PropertyCollection 由 PropertyValueCollection 组成

    【讨论】:

    • 这是正确的方法,看来 PropertyValueCollection 是正确枚举的关键。所有其他解决方案都建议使用另一种间接索引(或者都不起作用)。
    • 完美,除了我需要在.Value 上使用.ToString,因为它不能被隐式转换。
    【解决方案2】:

    PropertyCollection 有一个 PropertyName 集合 - 它是一个字符串集合(参见 PropertyCollection.ContainsPropertyCollection.Item 两者都采用一个字符串)。

    您通常可以调用GetEnumerator 以允许您使用通常的枚举方法来枚举集合 - 在这种情况下,您将获得一个包含字符串键的 IDictionary,然后是每个项目/值的对象。

    【讨论】:

    • 最好在 foreach 循环中使用隐式转换。
    【解决方案3】:
    usr = result.GetDirectoryEntry();
    foreach (string strProperty in usr.Properties.PropertyNames)
    {
       Console.WriteLine("{0}:{1}" ,strProperty, usr.Properties[strProperty].Value);
    }
    

    【讨论】:

      【解决方案4】:
      foreach(var k in collection.Keys) 
      {
           string name = k;
           string value = collection[k];
      }
      

      【讨论】:

        【解决方案5】:

        编辑我误读了 OP,因为我说的是 PropertyValueCollection 而不是 PropertyCollection。留下帖子,因为其他帖子正在引用它。

        我不确定我是否理解您的问题您只是想遍历集合中的每个值吗?如果是这样,此代码将起作用

        PropertyValueCollection collection = GetTheCollection();
        foreach ( object value in collection ) {
          // Do something with the value
        }
        

        打印出名称/值

        Console.WriteLine(collection.Name);
        Console.WriteLine(collection.Value);
        

        【讨论】:

          【解决方案6】:

          如果你只想要几件东西,你真的不需要做任何神奇的事情......

          使用语句:System、System.DirectoryServices 和 System.AccountManagement

          public void GetUserDetail(string username, string password)
          {
              UserDetail userDetail = new UserDetail();
              try
              {
                  PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, "mydomain.com", username, password);
          
                  //Authenticate against Active Directory
                  if (!principalContext.ValidateCredentials(username, password))
                  {
                      //Username or Password were incorrect or user doesn't exist
                      return userDetail;
                  }
          
                  //Get the details of the user passed in
                  UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext, principalContext.UserName);
          
                  //get the properties of the user passed in
                  DirectoryEntry directoryEntry = userPrincipal.GetUnderlyingObject() as DirectoryEntry;
          
                  userDetail.FirstName = directoryEntry.Properties["givenname"].Value.ToString();
                  userDetail.LastName = directoryEntry.Properties["sn"].Value.ToString();
              }
              catch (Exception ex)
              {
                 //Catch your Excption
              }
          
              return userDetail;
          }
          

          【讨论】:

            【解决方案7】:

            我在另一个帖子上发布了我的答案,然后发现这个帖子问了一个类似的问题。

            我尝试了建议的方法,但在转换到 DictionaryEntry 时总是遇到无效转换异常。有了 DictionaryEntry,FirstOrDefault 之类的东西就很时髦。所以,我只是这样做:

            var directoryEntry = adUser.GetUnderlyingObject() as DirectoryEntry;
            directoryEntry.RefreshCache();
            var propNames = directoryEntry.Properties.PropertyNames.Cast<string>();
            var props = propNames
                .Select(x => new { Key = x, Value = directoryEntry.Properties[x].Value.ToString() })
                .ToList();
            

            有了这些,我就可以轻松地直接通过 Key 查询任何属性。使用合并和安全导航运算符允许默认为空字符串或其他任何内容..

            var myProp = props.FirstOrDefault(x => x.Key == "someKey"))?.Value ?? string.Empty;
            

            如果我想查看所有的道具,这是一个类似的 foreach。

            foreach (var prop in props)
            {
                 Console.WriteLine($"{prop.Key} - {prop.Value}");
            }
            

            请注意,“adUser”对象是 UserPrincipal 对象。

            【讨论】:

              【解决方案8】:
              public string GetValue(string propertyName, SearchResult result)
              {
                  foreach (var property in result.Properties)
                  {
                      if (((DictionaryEntry)property).Key.ToString() == propertyName)
                      {
                          return ((ResultPropertyValueCollection)((DictionaryEntry)property).Value)[0].ToString();
                      }
                  }
                  return null;
              }
              

              【讨论】:

                【解决方案9】:

                我不确定为什么很难找到答案,但是通过下面的代码,我可以遍历所有属性并提取我想要的属性并将代码重用于任何属性。 如果需要,您可以以不同的方式处理目录条目部分

                getAnyProperty("[servername]", @"CN=[cn name]", "description");
                
                   public List<string> getAnyProperty(string originatingServer, string distinguishedName, string propertyToSearchFor)
                    {
                        string path = "LDAP://" + originatingServer + @"/" + distinguishedName;
                        DirectoryEntry objRootDSE = new DirectoryEntry(path, [Username], [Password]);
                // DirectoryEntry objRootDSE = new DirectoryEntry();
                
                        List<string> returnValue = new List<string>();
                        System.DirectoryServices.PropertyCollection properties = objRootDSE.Properties;
                        foreach (string propertyName in properties.PropertyNames)
                        {
                            PropertyValueCollection propertyValues = properties[propertyName];
                            if (propertyName == propertyToSearchFor)
                            {
                                foreach (string propertyValue in propertyValues)
                                {
                                    returnValue.Add(propertyValue);
                                }
                            }
                        }
                
                        return returnValue;
                    }
                

                【讨论】:

                  【解决方案10】:

                  我认为有一个更简单的方法

                  foreach (DictionaryEntry e in child.Properties) 
                  {
                      Console.Write(e.Key);
                      Console.Write(e.Value);
                  }
                  

                  【讨论】:

                  • 我收到了 System.InvalidCastException:指定的演员表无效。使用时。
                  • 这是正确的方法,但使用了错误的类型。根据 shahkalpesh 的回答,PropertyCollection 包含 PropertyValueCollection 对象,而不是 DictionaryEntry 对象。
                  猜你喜欢
                  • 2015-07-15
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-02-20
                  • 1970-01-01
                  • 2011-07-04
                  相关资源
                  最近更新 更多