如何将 PropertyValueCollection 转换为 C# 列表? (结果属性集合和搜索结果)
我编写了一个查询来从 Active Directory 中读取一些内容,但结果是某种“ResultPropertyCollection”,这是我不熟悉的东西。
如何将此结果转换为我更熟悉的列表(例如通用列表),以便我可以对结果执行某些操作?
DirectoryEntry de = new DirectoryEntry("LDAP://" + this.rootLDAP);
DirectorySearcher ds = new DirectorySearcher(de, "(& (objectcategory=Group))");
ds.PropertiesToLoad.Add("samaccountname");
ds.PropertiesToLoad.Add("memberof");
ds.PropertiesToLoad.Add("samaccounttype");
ds.PropertiesToLoad.Add("grouptype");
ds.PropertiesToLoad.Add("member");
ds.PropertiesToLoad.Add("objectcategory");
var r = ( from SearchResult sr in ds.FindAll() select sr ) .ToArray();
I've written a query to read some stuff from Active Directory, but the result is some kind of "ResultPropertyCollection", which is something I'm not familiar with.
How can I convert this result to a list (like Generic List) that I'm more familiar with so I can do something with the results?
DirectoryEntry de = new DirectoryEntry("LDAP://" + this.rootLDAP);
DirectorySearcher ds = new DirectorySearcher(de, "(& (objectcategory=Group))");
ds.PropertiesToLoad.Add("samaccountname");
ds.PropertiesToLoad.Add("memberof");
ds.PropertiesToLoad.Add("samaccounttype");
ds.PropertiesToLoad.Add("grouptype");
ds.PropertiesToLoad.Add("member");
ds.PropertiesToLoad.Add("objectcategory");
var r = ( from SearchResult sr in ds.FindAll() select sr ) .ToArray();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(4)
一开始我也很困惑,但这都是获取属性集合项类型的问题。一旦我发现属性项的类型是 System.Collections.DictionaryEntry 并且该值是由 ResultPropertyValueCollection 项组成的集合,就可以进行简单的迭代。
这是我最终得到的结果:
bool attemptResult = false;
string ldap = "LDAP:<Your A.D. specific connection string>";
DirectoryEntry entry = new DirectoryEntry(ldap, username, password, AuthenticationTypes.Secure);
try
{
DirectorySearcher searcher = new DirectorySearcher(entry);
searcher.Filter = "(&(objectClass=User)(sAMAccountName=" + username + "))";
SearchResult one = searcher.FindOne();
attemptResult = true;
string properties = "";
string userData = JsonConvert.SerializeObject(one.Properties);
foreach (System.Collections.DictionaryEntry de in one.Properties) {
properties += (properties.Length > 0 ? ",\n" : "");
properties += "\"" + de.Key + "\": [";
ResultPropertyValueCollection vc = ((ResultPropertyValueCollection)de.Value);
foreach (var val in vc) {
properties += "{\"type\": \"" + val.GetType().Name + "\", \"value\"; \"" + val.ToString() + "\"}";
}
properties += "]";
}
properties = properties.Replace("}{", "},{");
string displayName = one.Properties["displayname"][0].ToString();
string givenName = one.Properties["givenname"][0].ToString();
string lastname = one.Properties["sn"][0].ToString();
}
catch (Exception e) {
//log the error;
}
return attemptResult;
请注意使用 JsonConvert.SerializeObject 快速轻松地转换为字符串。这是一步转换。
我还使用 foreach 迭代执行了到字符串的个性化转换。这更像是一种自学练习,我从中了解到,在获得命名属性的值后,我可以找出该属性是否有零个、一个或多个值,并采取相应的行动,甚至在必要时验证对象类型。
这是在字符串变量、属性和 userData 中获得的值(出于隐私原因删除了一些项目)。
/* Value of userData Obtained with Json serializator*/
{"givenname":["First Name"],"samaccountname":["User.Name"],"cn":["First Name Last Name"],"pwdlastset":[131641282827115142],"whencreated":["2017-10-12T22:16:43"],"badpwdcount":[0],"displayname":["First Name Last Name"],"lastlogon":[131648243091569908],"samaccounttype":[805306368],"countrycode":[0],"objectguid":["SOMETHINGBASE64LIKE=="],"usnchanged":[52144153],"manager":["CN=The Name Of A Person,OU=Department Name,OU=City,OU=GroupName ,DC=Domain,DC=com"],"whenchanged":["2018-03-02T23:21:54"],"name":["First Name Last Name"],"objectsid":["SOMETHINGBASE64LIKE=="],"lastlogoff":[0],"lockouttime":[0],"badpasswordtime":[131647632246625185],"instancetype":[4],"primarygroupid":[513],"objectcategory":["CN=Person,CN=Schema,CN=Configuration,DC=Domain,DC=com"],"logoncount":[1073],"useraccountcontrol":[512],"description":["Some text"],"dscorepropagationdata":["1601-01-01T00:00:00"],"distinguishedname":["CN=First Name Last Name,OU=Department Name,OU=City,OU=GroupName ,DC=Domain,DC=com"],"objectclass":["top","person","organizationalPerson","user"],"adspath":["LDAP://Server/CN=First Name Last Name,OU=Department Name,OU=City,OU=GroupName ,DC=Domain,DC=com"],"usncreated":[39705915],"lastlogontimestamp":[131643676396776065],"userprincipalname":["[email protected]"],"employeeid":["99999"],"accountexpires":[9223372036854775807],"department":["DepartmentName"],"codepage":[0],"sn":["Last Name"]}
/* value of properties, the string I concatenated */
"givenname": [{"type": "String", "value"; "First Name"}],
"samaccountname": [{"type": "String", "value"; "User.Name"}],
"cn": [{"type": "String", "value"; "First Name Last name"}],
"pwdlastset": [{"type": "Int64", "value"; "131641282827115142"}],
"whencreated": [{"type": "DateTime", "value"; "12/10/2017 10:16:43 p. m."}],
"badpwdcount": [{"type": "Int32", "value"; "0"}],
"displayname": [{"type": "String", "value"; "First Name Last name"}],
"lastlogon": [{"type": "Int64", "value"; "131648243091569908"}],
"samaccounttype": [{"type": "Int32", "value"; "805306368"}],
"countrycode": [{"type": "Int32", "value"; "0"}],
"objectguid": [{"type": "Byte[]", "value"; "System.Byte[]"}],
"usnchanged": [{"type": "Int64", "value"; "52144153"}],
"manager": [{"type": "String", "value"; "CN=Some Person Name,OU=Department name,OU=City,OU=Group Name,DC=Domain,DC=com"}],
"whenchanged": [{"type": "DateTime", "value"; "2/3/2018 11:21:54 p. m."}],
"name": [{"type": "String", "value"; "First Name Last name"}],
"objectsid": [{"type": "Byte[]", "value"; "System.Byte[]"}],
"lastlogoff": [{"type": "Int64", "value"; "0"}],
"lockouttime": [{"type": "Int64", "value"; "0"}],
"badpasswordtime": [{"type": "Int64", "value"; "131647632246625185"}],
"instancetype": [{"type": "Int32", "value"; "4"}],
"primarygroupid": [{"type": "Int32", "value"; "513"}],
"objectcategory": [{"type": "String", "value"; "CN=Person,CN=Schema,CN=Configuration,DC=Domain,DC=com"}],
"logoncount": [{"type": "Int32", "value"; "1073"}],
"useraccountcontrol": [{"type": "Int32", "value"; "512"}],
"description": [{"type": "String", "value"; "13065, PROGRAMADOR SENIOR"}],
"dscorepropagationdata": [{"type": "DateTime", "value"; "1/1/1601 12:00:00 a. m."}],
"distinguishedname": [{"type": "String", "value"; "CN=First Name Last name,OU=Department name,OU=City,OU=Group Name,DC=Domain,DC=com"}],
"objectclass": [{"type": "String", "value"; "top"},{"type": "String", "value"; "person"},{"type": "String", "value"; "organizationalPerson"},{"type": "String", "value"; "user"}],
"adspath": [{"type": "String", "value"; "LDAP://SERVERNAME/CN=First Name Last name,OU=Department name,OU=City,OU=Group Name,DC=Domain,DC=com"}],
"usncreated": [{"type": "Int64", "value"; "39705915"}],
"lastlogontimestamp": [{"type": "Int64", "value"; "131643676396776065"}],
"userprincipalname": [{"type": "String", "value"; "[email protected]"}],
"employeeid": [{"type": "String", "value"; "13065"}],
"accountexpires": [{"type": "Int64", "value"; "9223372036854775807"}],
"department": [{"type": "String", "value"; "IT"}],
"codepage": [{"type": "Int32", "value"; "0"}],
"sn": [{"type": "String", "value"; "Last name"}]
正如您所看到的,某些属性具有多个值。因此,要获得简单的通用属性列表,您需要决定如何处理多值属性。最有可能的是,您希望将所有值都作为字符串,因此可以使用合适的分隔符简单地连接多个值。
我们不能使用这样的东西吗? (因为我现在正在使用它)
ds.FindAll().Cast<SearchResult>().Select(result => new Address(result.GetDirectoryEntry())).ToList();
public class Address
{
internal Address(DirectoryEntry entry)
{
//
// You can get one or more of the following properties:
//
//
// objectClass
// cn
// description
// givenName
// distinguishedName
// instanceType
// whenCreated
// whenChanged
// displayName
// uSNCreated
// memberOf
// uSNChanged
// homeMTA
// proxyAddresses
// homeMDB
// mDBUseDefaults
// mailNickname
// protocolSettings
// name
// objectGUID
// userAccountControl
// badPwdCount
// codePage
// countryCode
// badPasswordTime
// lastLogon
// pwdLastSet
// primaryGroupID
// objectSid
// accountExpires
// logonCount
// sAMAccountName
// sAMAccountType
// showInAddressBook
// legacyExchangeDN
// userPrincipalName
// lockoutTime
// objectCategory
// dSCorePropagationData
// lastLogonTimestamp
// textEncodedORAddress
// mail
// msExchPoliciesExcluded
// msExchMailboxTemplateLink
// msExchRecipientDisplayType
// msExchUserCulture
// msExchVersion
// msExchRecipientTypeDetails
// msExchHomeServerName
// msExchALObjectVersion
// msExchMailboxSecurityDescriptor
// msExchUserAccountControl
// msExchMailboxGuid
// nTSecurityDescriptor
// As an example we get only two properties
this.DisplayName = (string)entry.Properties["displayName"].Value;
this.Mail = (string)entry.Properties["mail"].Value;
Manager = (string)entry.Properties["manager"].Value;
}
public string DisplayName
{
get;
private set;
}
public string Manager
{
get;
private set;
}
public string Mail
{
get;
private set;
}
}
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
如果您只需要
SearchResult
类型的列表,您可以使用:但由于您需要搜索结果中的实际值,因此您需要做更多的工作。
基本上,该集合包含您为搜索定义的所有属性 - 至少只要它们包含值!
所以实际上,您需要做的是创建一个类来保存这些值。两个元素
memberOf
和member
本身可以包含多个值(它们是 AD 中的“多值”属性) - 因此您需要这些值的字符串列表:然后,一旦获得搜索结果,您需要迭代结果并为每个搜索结果创建
YourType
的新实例,并将它们粘贴到List
中>:在该方法中,您需要检查每个值的
.Properties
集合并提取它:If you only want a list of
SearchResult
types, you could use:But since you want the actual values from the search results, you need to do more work.
Basically, that collection contains all the properties you've defined for the search - at least as long as they contain a value!
So really, what you need to do is create a class to hold those values. The two elements
memberOf
andmember
can themselves contain multiple values (they're "multi-valued" attributes in AD) - so you'll need a list of strings for these:Then, once you have your search result, you need to iterate over the results and create new instances of
YourType
for each search result, and stick those into aList<YourType>
:and in that method, you need to inspect the
.Properties
collection for each value and extract it: