Как выполнить цикл через PropertyCollection
может ли кто - нибудь привести пример того, как выполнить цикл через систему.DirectoryServices.PropertyCollection и вывести имя и значение свойства?
Я использую C#.
@JaredPar-PropertyCollection не имеет свойства имя / значение. Он имеет PropertyNames и Значения, Тип System.Коллекция.Интерфейс ICollection. Я не знаю тип объекта basline, который составляет объект 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));
}
}
}
}
10 ответов
PropertyCollection имеет коллекцию PropertyName-которая представляет собой коллекцию строк (см. PropertyCollection.Содержит и PropertyCollection.Пункт оба из которых принимают строку).
можно назвать GetEnumerator чтобы вы могли перечислять коллекцию, используя обычные методы перечисления - в этом случае вы получите IDictionary, содержащий строковый ключ, а затем объект для каждого элемента/значений.
см. значение 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);
}
EDIT: PropertyCollection состоит из PropertyValueCollection
usr = result.GetDirectoryEntry();
foreach (string strProperty in usr.Properties.PropertyNames)
{
Console.WriteLine("{0}:{1}" ,strProperty, usr.Properties[strProperty].Value);
}
редактировать Я неправильно истолковал OP как сказав PropertyValueCollection не PropertyCollection. Оставив пост, потому что других должностей referenceing его.
Я не уверен, что понимаю, о чем вы спрашиваете, вы просто хотите перебрать каждое значение в коллекции? Если этот код будет работать
PropertyValueCollection collection = GetTheCollection();
foreach ( object value in collection ) {
// Do something with the value
}
Распечатать имя / значение
Console.WriteLine(collection.Name);
Console.WriteLine(collection.Value);
Я думаю, что есть более простой способ
foreach (DictionaryEntry e in child.Properties)
{
Console.Write(e.Key);
Console.Write(e.Value);
}
вам действительно не нужно делать ничего волшебного, если вы хотите всего несколько предметов...
Использование Операторов: System, 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;
}
Я отправил свой ответ в другой поток, а затем нашел этот поток, задающий аналогичный вопрос.
Я пробовал предложенные методы, но я всегда получаю недопустимое исключение cast при приведении к 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();
С этим на месте, я могу легко запросить любое свойство непосредственно ключом. Использование операторов coalesce и safe navigation позволяет по умолчанию пустая струна или что-то в этом роде..
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.
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;
}
Я не уверен, почему это было так трудно найти ответ, но с приведенным ниже кодом я могу перебрать все свойства и вытащить тот, который я хочу, и повторно использовать код для любого свойства. Вы можете обрабатывать часть записи каталога по-разному, если хотите
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;
}