web-dev-qa-db-ja.com

PropertyCollectionをループするにはどうすればよいですか

System.DirectoryServices.PropertyCollectionをループして、プロパティの名前と値を出力する方法の例を誰かが提供できますか?

私はC#を使用しています。

@ JaredPar-PropertyCollectionにはName/Valueプロパティがありません。 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));                
            }
        }      
    }  
}
21

PropertyCollectionには、文字列のコレクションであるPropertyNameコレクションがあります( PropertyCollection.Contains および PropertyCollection.Item を参照してください。どちらも文字列を取ります)。

通常、 GetEnumerator を呼び出して、通常の列挙メソッドを使用してコレクションを列挙できるようにします。この場合、文字列キーを含むIDictionaryを取得し、次に各アイテム/値のオブジェクトを取得します。 。

5

ウォッチウィンドウで実行時に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 で構成されています

30
shahkalpesh
usr = result.GetDirectoryEntry();
foreach (string strProperty in usr.Properties.PropertyNames)
{
   Console.WriteLine("{0}:{1}" ,strProperty, usr.Properties[strProperty].Value);
}
5
Vladimir
foreach(var k in collection.Keys) 
{
     string name = k;
     string value = collection[k];
}
2
antonioh

なぜこれが答えを見つけるのが難しいのかわかりませんが、以下のコードを使用して、すべてのプロパティをループし、必要なプロパティをプルして、任意のプロパティにコードを再利用できます。必要に応じて、ディレクトリエントリ部分を別の方法で処理できます

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

別のスレッドに回答を投稿したところ、このスレッドが同様の質問をしていることがわかりました。

提案されたメソッドを試しましたが、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オブジェクトであることに注意してください。

0
long2know

[〜#〜] edit [〜#〜] OPをPropertyCollectionではなくPropertyValueCollectionと言ったと誤解しました。他の投稿がそれを参照しているため、投稿を残します。

あなたが何を求めているのか理解できません。コレクション内の各値をループしたいだけですか?もしそうなら、このコードは機能します

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

名前/値を印刷する

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

もっと簡単な方法があると思います

foreach (DictionaryEntry e in child.Properties) 
{
    Console.Write(e.Key);
    Console.Write(e.Value);
}
0
user76071
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;
}
0
Mohammed Othman

いくつかのアイテムが必要な場合は、魔法のようなことをする必要はありません...

ステートメントの使用: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;
}
0
user2680296