net example asp c# web-services .net-4.0 pagination ldap

example - oauth web api c#



En.Net 4.0, ¿puede DirectorySearch devolver los resultados LDAP de una manera que me permita navegar por ellos? (3)

Estoy trabajando en C # y estoy intentando utilizar DirectorySearch para consultar los grupos de un servidor LDAP de Microsoft ActiveDirectory extremadamente grande.

Entonces, en mi aplicación, tendré una lista paginada de grupos, con capacidad de búsqueda. Naturalmente, no quiero perjudicar mi servidor LDAP al pasarme el conjunto de resultados completo para estas consultas cada vez que pulso "Página siguiente".

¿Hay alguna manera, utilizando DirectorySearch, de recuperar SOLAMENTE los resultados de una sola página arbitraria, en lugar de devolver todo el conjunto de resultados en una sola llamada al método?

Preguntas similares:

Existen muchas preguntas como esta, en las que alguien pregunta sobre la búsqueda (es decir, del servidor LDAP al servidor de aplicaciones) y obtiene respuestas que incluyen PageSize y SizeLimit. Sin embargo, esas propiedades solo afectan la búsqueda entre el servidor C # y el servidor LDAP, y al final, los únicos métodos relevantes que tiene DirectorySearch son FindOne () y FindAll ().

Lo que busco es básicamente "FindPaged (pageSize, pageNumber)" (el pageNumber es el bit realmente importante. No solo quiero los primeros 1000 resultados, quiero (por ejemplo) el 100 ° set de 1000 resultados La aplicación no puede esperar a que se pasen 100.000 registros del servidor LDAP al servidor de la aplicación, incluso si están divididos en fragmentos de 1.000 registros.

Entiendo que DirectoryServices.Protocols tiene SearchRequest, que (¿creo?) Le permite usar un "PageResultRequestControl", que parece que tiene lo que estoy buscando (aunque parece que la información de paginación viene en "cookies", que No estoy seguro de cómo se supone que debo recuperar). Pero si hay una forma de hacerlo sin tener que volver a escribir todo para usar Protocolos, preferiría no tener que hacerlo.

Simplemente no puedo imaginar que no haya forma de hacer esto ... Incluso SQL tiene Row_Number.

ACTUALIZACIÓN: El PageResultRequestControl no ayuda: es solo de avance y secuencial (debe llamar y obtener los primeros N resultados antes de poder obtener el token de "cookie" necesario para realizar una llamada y obtener el resultado N + 1).

Sin embargo, la cookie parece tener algún tipo de ordenamiento reproducible ... En un conjunto de resultados en el que estaba trabajando, iteraba uno por uno a través de los resultados, y cada vez que la cookie salía así:

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

Cuando iteraba de dos en dos, obtuve los mismos números (11, 16). Esto me hace pensar que si pudiera descifrar el código de cómo se generan esos números, podría crear una cookie ad-hoc, que me daría exactamente la paginación que estoy buscando.


El PageResultRequestControl es de hecho la manera de hacer esto, es parte del protocolo LDAP. Tendrás que descubrir qué implica eso para tu código, lo siento. Debería haber una manera de usarlo desde donde se encuentre, pero, una vez dicho esto, estoy trabajando en Java y acabo de escribir una docena de controles de solicitud y clases de operación extendida para utilizar con JNDI para que pueda podría estar fuera de suerte ... o podría tener que hacer como lo hice. Advertencia, el análisis ASN.1 sigue no muy atrás: - |


Lamentablemente, parece que no puede haber una manera de hacerlo dado las bibliotecas actuales de C #.

Todas las bibliotecas LDAP C # 4.0 estándar devuelven resultados Top-N (Como en, FindAll (), que devuelve todos los resultados, FindOne (), que devuelve el primer resultado, o SearchResult con PageResultRequestControl, que devuelve resultados N a N + M pero requiere que recupere los resultados 1 a N-1 antes de que tenga un token de cookies que puede pasar con la solicitud para obtener el siguiente conjunto.

No he podido encontrar ninguna biblioteca de LDAP de terceros que lo permita.

A menos que se encuentre una mejor solución, mi camino a seguir será modificar la interfaz para mostrar los resultados X superiores, sin capacidades de paginación del cliente (obviamente aún usando paginación del lado del servidor según corresponda).

Es posible que busque un sistema de paginación de solo reenvío en una fecha posterior, pasando la cookie actualizada al cliente con la respuesta y devolviéndola con un clic del tipo de botón "Más resultados". Puede valer la pena continuar en una fecha posterior, independientemente de si estas cookies pueden ser hechas a mano.

ACTUALIZACIÓN: hablé con el soporte técnico de Microsoft y confirmé esto: no hay forma de realizar paginación dinámica con servidores LDAP. Esta es una limitación de los servidores LDAP.

Puede usar Protocolos y el control de paginación (si su servidor LDAP lo admite) para avanzar a voluntad, pero no existe un estándar entre servidores (o incluso una versión cruzada) para la cookie, por lo que no puede crear su propio , y no hay garantía de que la cookie se pueda reutilizar para consultas repetidas.

Una solución completa implica el uso de protocolos (con paginación como se indica anteriormente) para extraer su conjunto de resultados paginable en SQL, ya sea en una tabla temporal o en una tabla de almacenamiento permanente, y permitirle al usuario buscar y clasificar ESE conjunto de resultados de la manera tradicional. Tenga en cuenta que sus resultados no estarán precisamente actualizados, pero con algunas actualizaciones inteligentes de caché puede minimizar ese riesgo.


Tal vez quiera iterar a través de sus "páginas" utilizando el atributo de rango en consecuencia:

----copiar pegar----

Esta muestra recupera las entradas 0-500, inclusive.

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(); // Each entry contains a property name and the path (ADsPath). // The following code returns the property name from the PropertyCollection. 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); }

----copiar pegar----

Para más información, ver:

Enumeración de miembros en un grupo grande https://msdn.microsoft.com/en-us/library/ms180907.aspx

Recuperación de rango de valores de atributo https://msdn.microsoft.com/en-us/library/cc223242.aspx

Búsqueda mediante recuperación de rango https://msdn.microsoft.com/en-us/library/aa367017.aspx