c# - 如何使用 Novell.Directory.Ldap.NETStandard 在具有 > 10000 个条目的 Ldap 服务器上进行分页搜索?
问题描述
这类似于如何在具有大量用户的 Ldap 服务器上进行分页搜索?但建议的解决方案对我们不起作用。
我们使用 Novell.Directory.Ldap.NETStandard 库,我们需要从 Active Directory 中获取超过 10000 个条目。我们使用 LdapVirtualListControl 来处理分页,但该控件需要另一个控件:LdapSortControl。Active Directory 有一个默认的排序限制 (10000),如果结果超过该限制,将发送错误 53(不愿意执行)。如果省略“检测最大结果错误”,我们将获得 LdapException: 'Unavailable Critical Extension'。
// Connection
var ldapConn = new LdapConnection()
{
SecureSocketLayer = true,
};
ldapConn.UserDefinedServerCertValidationDelegate += (sender, certificate, chain, sslPolicyErrors) => true;
ldapConn.Connect(host, 636);
ldapConn.Bind(username, password);
var searchConstraints = (LdapSearchConstraints)ldapConn.SearchConstraints.Clone();
int contentCount = 0, count = 0, startIndex = 1, pageSize = 1000;
bool exit;
do
{
// Add Virtual List Control
searchConstraints.setControls(new List<LdapControl>
{
{ new LdapVirtualListControl(startIndex, 0, pageSize - 1, contentCount) },
{ new LdapSortControl(new LdapSortKey[1] { new LdapSortKey("name") },true) }
}.ToArray());
// Perform search
var searchResult = ldapConn.Search(container, scope, query, null, false, searchConstraints);
// Get entries in page
var inPageCount = 0;
while (searchResult.hasMore())
{
// Detect max result error
LdapSortResponse ldapControl = searchResult.ResponseControls?.OfType<LdapSortResponse>().FirstOrDefault();
if (ldapControl != null && ldapControl.ResultCode == 53) throw new LdapResultLimitExceeded(string.Format("ActiveDirectory: Ldap result limit exceeded in {0}.", container));
searchResult.next();
inPageCount++;
}
// Check for more pages
var control = FindResponseControl(searchResult, ActiveDirectoryService.LDAP_SERVER_VIRTUAL_LIST_VIEW_OID);
if (control != null)
{
var response = new LdapVirtualListResponse(control.ID, control.Critical, control.getValue());
startIndex += pageSize;
contentCount = response.ContentCount;
if (count + pageSize > contentCount) count = contentCount; else count += inPageCount;
}
exit = control == null;
} while (count < contentCount && contentCount > 0 && !exit);
我们应该如何处理超过 10000 个条目的搜索?
解决方案
如果您只需要按顺序遍历结果集,则不需要使用 LVL。我建议使用简单的分页结果控件(https://stackoverflow.com/a/59747510/4700228)