7 Stimmen

Im Rahmen von .Net 4.0 kann DirectorySearch LDAP-Ergebnisse auf eine Weise zurückgeben, die es mir ermöglicht, durch sie zu blättern?

Ich arbeite mit C# und versuche, DirectorySearch zu verwenden, um die Gruppen eines extrem großen Microsoft ActiveDirectory LDAP-Servers abzufragen.

Also werde ich in meiner Anwendung eine paginierte Liste von Gruppen mit Suchfunktion haben. Natürlich möchte ich meinen LDAP-Server nicht belasten, indem er mir jedes Mal, wenn ich auf "Nächste Seite" klicke, das gesamte Ergebnis für diese Abfragen übergibt.

Gibt es eine Möglichkeit, mit DirectorySearch NUR die Ergebnisse einer einzelnen willkürlichen Seite abzurufen, anstatt das gesamte Ergebnisset in einem Methodenaufruf zurückzugeben?

Ähnliche Fragen:

Es gibt viele Fragen wie diese, bei denen jemand nach der Seitenzahl (vom LDAP-Server zum App-Server) fragt und Antworten erhält, die PageSize und SizeLimit beinhalten. Diese Eigenschaften wirken sich jedoch nur auf die Seitenumbrüche zwischen dem C#-Server und dem LDAP-Server aus, und letztendlich sind die einzigen relevanten Methoden, die DirectorySearch hat, FindOne() und FindAll().

Was ich suche, ist im Grunde genommen "FindPaged(pageSize, pageNumber)" (wobei die Seitennummer wirklich wichtig ist. Ich möchte nicht nur die ersten 1000 Ergebnisse, sondern zum Beispiel den 100. Satz von 1000 Ergebnissen. Die App kann nicht darauf warten, dass 100.000 Datensätze vom LDAP-Server an den App-Server übergeben werden, selbst wenn sie in 1.000er-Chunks aufgeteilt sind.

Ich verstehe, dass DirectoryServices.Protocols SearchRequest hat, mit dem Sie wahrscheinlich einen "PageResultRequestControl" verwenden können, der anscheinend das bietet, wonach ich suche (obwohl es so aussieht, als käme die Seitenumbruchsinformation in "Cookies", die ich nicht weiß, wie ich sie abrufen soll). Aber wenn es einen Weg gibt, dies zu tun, ohne das gesamte Ding neu schreiben zu müssen, um Protokolle zu verwenden, würde ich das lieber vermeiden.

Ich kann mir einfach nicht vorstellen, dass es keinen Weg gibt, dies zu tun... Sogar SQL hat Row_Number.

UPDATE: Der PageResultRequestControl hilft nicht - er ist nur vorwärts und sequenziell (Sie müssen die ersten N Ergebnisse abrufen, bevor Sie das "Cookie"-Token erhalten, das für einen Aufruf benötigt wird, um das Ergebnis N+1 zu erhalten).

Das Cookie scheint jedoch eine Art reproduzierbare Reihenfolge zu haben... Bei einem Ergebnisdatensatz, an dem ich gearbeitet habe, habe ich jedes Mal, wenn ich durch die Ergebnisse iteriert habe, folgendes Cookie erhalten:

1: {8, 0, 0, 0}
2: {11, 0, 0, 0}
3: {12, 0, 0, 0}
4: {16, 0, 0, 0}

Als ich zwei nach zwei durchiteriert habe, habe ich die gleichen Zahlen erhalten (11, 16). Das lässt mich glauben, dass, wenn ich den Code herausfinden könnte, wie diese Zahlen generiert werden, ich ein Cookie ad-hoc erstellen könnte, das mir genau das Paging geben würde, das ich suche.

3voto

user207421 Punkte 297318

Der PageResultRequestControl ist tatsächlich der richtige Weg, um dies zu tun, er ist Teil des LDAP-Protokolls. Du musst nur herausfinden, was das für deinen Code bedeutet, tut mir leid. Es sollte einen Weg geben, es von dort aus zu verwenden, aber, abgesehen davon, arbeite ich in Java und musste gerade ein Dutzend oder so Anforderungssteuerungen und erweiterte Betriebsklassen für die Verwendung mit JNDI schreiben, also könnte es sein, dass du Pech hast ... oder du musst wie ich es getan habe. Warnung, ASN.1-Analyse folgt nicht weit dahinter :-|

3voto

ChristopherBass Punkte 179

Leider gibt es anscheinend keine Möglichkeit, dies mit den aktuellen C#-Bibliotheken zu tun.

Alle Standard-C#4.0-LDAP-Bibliotheken geben Top-N-Ergebnisse zurück (z. B. FindAll(), das jedes Ergebnis zurückgibt, FindOne(), das das erste Ergebnis zurückgibt, oder SearchResult mit PageResultRequestControl, das Ergebnisse N bis N+M zurückgibt, aber erfordert, dass Sie zuvor Ergebnisse 1 bis N-1 abrufen, bevor Sie einen Cookie-Token haben, den Sie mit der Anforderung übergeben können, um den nächsten Satz zu erhalten.

I habe auch keine Drittanbieter-LDAP-Bibliotheken gefunden, die dies ermöglichen.

Sofern keine bessere Lösung gefunden wird, werde ich den Weg nehmen, die Schnittstelle zu ändern, um stattdessen die ersten X Ergebnisse anzuzeigen, ohne Client-seitige Paging-Funktionen (natürlich weiterhin Server-seitigem Paging verwenden, wenn nötig).

Vielleicht verfolge ich zu einem späteren Zeitpunkt ein nur vorwärts paging-System, indem ich den aktualisierten Cookie mit der Antwort an den Client übergebe und ihn mit einem Klick auf eine "Mehr Ergebnisse" Art von Schaltfläche zurückgebe. Es mag sinnvoll sein, dies zu einem späteren Zeitpunkt zu verfolgen, unabhängig davon, ob diese Cookies manuell erstellt werden können.

UPDATE: Ich habe mit dem Microsoft-Support gesprochen und dies bestätigt - Es gibt keine Möglichkeit, dynamisches Paging mit LDAP-Servern durchzuführen. Dies ist eine Einschränkung der LDAP-Server selbst.

Sie können Protokolle und die Paging-Steuerung (falls Ihr LDAP-Server dies unterstützt) verwenden, um jederzeit vorwärts zu gehen, aber es gibt keinen plattformübergreifenden (oder sogar plattformübergreifenden) Standard für den Cookie, sodass Sie Ihren eigenen vernünftigerweise nicht erstellen können und es keine Garantie gibt, dass der Cookie für wiederholte Abfragen wiederverwendet werden kann.

Eine vollständige Lösung besteht darin, Protokolle (mit Paging wie oben beschrieben) zu verwenden, um Ihr paginiertes Ergebnisset in SQL zu ziehen, sei es in eine temporäre Tabelle oder eine permanente Speichertabelle, und es Ihrem Benutzer zu ermöglichen, durch DAS Ergebnisset auf herkömmliche Weise zu blättern und zu sortieren. Beachten Sie, dass Ihre Ergebnisse nicht genau aktuell sein werden, aber mit einer cleveren Cache-Aktualisierung können Sie dieses Risiko minimieren.

0voto

Bernhard Punkte 2281

Vielleicht möchten Sie Ihre "Seiten" mithilfe des Bereichsattributes entsprechend durchlaufen:

----kopieren & einfügen----

Dieses Beispiel ruft Einträge 0-500, einschließlich, ab.

DirectoryEntry group = new DirectoryEntry("LDAP://CN=Sales,DC=Fabrikam,DC=COM");
DirectorySearcher groupMember = new DirectorySearcher
    (group,"(objectClass=*)",new string[]{"member;Range=0-500"},SearchScope.Base);
SearchResult result = groupMember.FindOne();
// Jeder Eintrag enthält einen Eigenschaftsnamen und den Pfad (ADsPath).
// Der folgende Code gibt den Eigenschaftsnamen aus der PropertyCollection zurück. 
String propName=String.Empty;
foreach(string s in result.Properties.PropertyNames)
{
    if ( s.ToLower() != "adspath")
    {
      propName = s;
      break;
    }
}
foreach(string member in result.Properties[propName])
{
     Console.WriteLine(member);
}

----kopieren & einfügen----

für weitere Informationen siehe:

Mitglieder in einer großen Gruppe auflisten https://msdn.microsoft.com/en-us/library/ms180907.aspx

Bereichsauswahl von Attributwerten https://msdn.microsoft.com/en-us/library/cc223242.aspx

Suchen unter Verwendung der Bereichsauswahl https://msdn.microsoft.com/en-us/library/aa367017.aspx

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