如何循环访问 PropertyCollection

发布于 2024-07-14 12:57:33 字数 1099 浏览 10 评论 0原文

任何人都可以提供如何循环遍历 System.DirectoryServices.PropertyCollection 并输出属性名称和值的示例吗?

我正在使用 C#。

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

再次@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));                
            }
        }      
    }  
}

Can anyone provide an example of how to loop through a System.DirectoryServices.PropertyCollection and output the property name and value?

I am using C#.

@JaredPar - The PropertyCollection does not have a Name/Value property. It does have a PropertyNames and Values, type System.Collection.ICollection. I do not know the basline object type that makes up the PropertyCollection object.

@JaredPar again - I originally mislabeled the question with the wrong type. That was my bad.

Update: Based on Zhaph - Ben Duguid input, I was able to develop the following code.

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));                
            }
        }      
    }  
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

筱果果 2024-07-21 12:57:34
foreach(var k in collection.Keys) 
{
     string name = k;
     string value = collection[k];
}
foreach(var k in collection.Keys) 
{
     string name = k;
     string value = collection[k];
}
厌味 2024-07-21 12:57:34

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

我尝试了建议的方法,但在转换为 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 对象。

I posted my answer on another thread, and then found this thread asking a similar question.

I tried the suggested methods, but I always get an invalid cast exception when casting to DictionaryEntry. And with a DictionaryEntry, things like FirstOrDefault are funky. So, I simply do this:

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();

With that in place, I can then easily query for any property directly by Key. Using the coalesce and safe navigation operators allows for defaulting to an empty string or whatever..

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

And if I wanted to look over all props, it's a similar foreach.

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

Note that the "adUser" object is the UserPrincipal object.

静水深流 2024-07-21 12:57:34

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

我不确定我明白你在问什么你只是想循环遍历集合中的每个值吗? 如果是这样,此代码将起作用

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

打印出名称/值

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

EDIT I misread the OP as having said PropertyValueCollection not PropertyCollection. Leaving post up because other posts are referenceing it.

I'm not sure I understand what you're asking Are you just wanting to loop through each value in the collection? If so this code will work

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

Print out the Name / Value

Console.WriteLine(collection.Name);
Console.WriteLine(collection.Value);
未蓝澄海的烟 2024-07-21 12:57:34

如果您只想要几个项目,您实际上不必做任何神奇的事情...

使用语句: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;
}

You really don't have to do anything magical if you want just a few items...

Using Statements: System, System.DirectoryServices, and 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;
}
喵星人汪星人 2024-07-21 12:57:34
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;
}
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;
}
演多会厌 2024-07-21 12:57:34

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

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;
    }

I'm not sure why this was so hard to find an answer to, but with the below code I can loop through all of the properties and pull the one I want and reuse the code for any property.
You can handle the directory entry portion differently if you want

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;
    }
-柠檬树下少年和吉他 2024-07-21 12:57:34

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

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

I think there's an easier way

foreach (DictionaryEntry e in child.Properties) 
{
    Console.Write(e.Key);
    Console.Write(e.Value);
}
无声无音无过去 2024-07-21 12:57:33

运行时在监视窗口中查看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 组成

See the value of PropertyValueCollection at runtime in the watch window to identify types of element, it contains & you can expand on it to further see what property each of the element has.

Adding to @JaredPar's code


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);
}

EDIT: PropertyCollection is made up of PropertyValueCollection

真心难拥有 2024-07-21 12:57:33

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

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

The PropertyCollection has a PropertyName collection - which is a collection of strings (see PropertyCollection.Contains and PropertyCollection.Item both of which take a string).

You can usually call GetEnumerator to allow you to enumerate over the collection, using the usual enumeration methods - in this case you'd get an IDictionary containing the string key, and then an object for each item/values.

初懵 2024-07-21 12:57:33
usr = result.GetDirectoryEntry();
foreach (string strProperty in usr.Properties.PropertyNames)
{
   Console.WriteLine("{0}:{1}" ,strProperty, usr.Properties[strProperty].Value);
}
usr = result.GetDirectoryEntry();
foreach (string strProperty in usr.Properties.PropertyNames)
{
   Console.WriteLine("{0}:{1}" ,strProperty, usr.Properties[strProperty].Value);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文