8 Stimmen

Wie konvertiert man PropertyValueCollection in eine Liste C#? (ResultPropertyCollection und SearchResult)

Ich habe eine Abfrage geschrieben, um einige Dinge aus Active Directory zu lesen, aber das Ergebnis ist eine Art von "ResultPropertyCollection", die etwas ist, das ich nicht vertraut bin mit.

Wie kann ich dieses Ergebnis in eine Liste (z. B. Generic List) umwandeln, mit der ich besser vertraut bin, so dass ich etwas mit den Ergebnissen anfangen kann?

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

13voto

marc_s Punkte 701497

Wenn Sie nur eine Liste von SearchResult Typen, die Sie verwenden können:

var r = ds.FindAll();

List<SearchResult> results = new List<SearchResult>();

foreach (SearchResult sr in r)
{
   results.Add(sr);
}

Da Sie aber die tatsächlichen Werte aus den Suchergebnissen benötigen, müssen Sie mehr Arbeit leisten.

Im Grunde genommen enthält diese Sammlung alle Eigenschaften, die Sie für die Suche definiert haben - zumindest, solange sie einen Wert enthalten!

Was Sie also tun müssen, ist eine Klasse zu erstellen, die diese Werte enthält. Die beiden Elemente memberOf y member können selbst mehrere Werte enthalten (es handelt sich um "mehrwertige" Attribute in AD) - Sie benötigen also eine Liste von Strings für diese:

public class YourType
{
    public string SamAccountName { get; set; }
    public int SamAccountType { get; set; }
    public int GroupType { get; set; }
    public string ObjectCategory { get; set; }
    public List<string> MemberOf { get; set; }
    public List<string> Member { get; set; }
}

Sobald Sie Ihr Suchergebnis haben, müssen Sie die Ergebnisse iterieren und neue Instanzen von YourType für jedes Suchergebnis, und fügen Sie diese in eine List<YourType> :

foreach(SearchResult sr in ds.FindAll())
{
    YourType newRecord = ConvertToYourType(sr);
}

und in dieser Methode müssen Sie die .Properties Sammlung für jeden Wert und extrahieren ihn:

public YourType ConvertToYourType(SearchResult result)
{
    YourType returnValue = new YourType();
    returnValue.MemberOf = new List<string>();
    returnValue.Member = new List<string>();

    if(result.Properties["samAccountName"] != null && result.Properties["samAccountName"].Count > 0)
    {
       returnValue.SamAccountName = result.Properties["samAccountName"][0].ToString();
    }

    // ..... and so on for each of your values you need to extract

    return returnValue;
}

4voto

Jahaziel Punkte 207

Auch ich war zunächst verwirrt, aber es ging nur darum, den Typ des Elements der Eigenschaftssammlung zu ermitteln. Nachdem ich herausgefunden hatte, dass der Typ des Eigenschaftselements System.Collections.DictionaryEntry ist und dass der Wert eine Sammlung aus ResultPropertyValueCollection-Elementen ist, waren einfache Iterationen möglich.

Ich habe folgendes Ergebnis erzielt:

        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;

Beachten Sie die schnelle und einfache Konvertierung in einen String mit JsonConvert.SerializeObject. Dies ist eine Konvertierung in einem Schritt.

Ich habe auch eine personalisierte Konvertierung in eine Zeichenkette durchgeführt, indem ich foreach-Iterationen verwendet habe. Dies war eher eine Übung zum Selbststudium, aus der ich gelernt habe, dass ich, nachdem ich den Wert für eine benannte Eigenschaft erhalten habe, herausfinden kann, ob die Eigenschaften null, einen oder mehrere Werte haben, und entsprechend handeln kann, wobei ich sogar den Objekttyp validieren kann, falls dies erforderlich ist.

Hier ist der Wert, der in beiden String-Variablen, Eigenschaften und userData erhalten wurde (einige Elemente wurden aus Datenschutzgründen entfernt).

/* 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":["User.Name@Domain.com"],"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"; "User.Name@Domain.com"}],
"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"}]

Wie Sie sehen können, haben einige der Eigenschaften mehr als einen Wert. Um eine einfache allgemeine Liste von Eigenschaften zu erhalten, müssen Sie also entscheiden, was Sie mit mehrwertigen Eigenschaften tun wollen. Höchstwahrscheinlich möchten Sie alle Werte als Strings haben, so dass mehrere Werte einfach mit einem geeigneten Trennzeichen verkettet werden können.

-1voto

The Godfather Punkte 825

Dies ist möglicherweise keine vollständige Lösung oder die richtige Antwort. Nachfolgend finden Sie nur eine Lösung zur Konvertierung SearchResultCollection a List

SearchResultCollection rc = ds.FindAll();

List<SearchResult> resultList = rc.Cast<SearchResult>().ToList();

// Now loop through the list
foreach(SearchResult sr in resultList)
{
    //.. get properties here
}

-1voto

Maitrey684 Punkte 734

Können wir nicht etwas in dieser Art verwenden? (Wie ich es derzeit benutze)

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X