在.net 4.0中,DirectorySearch是否可以以一种允许我浏览它们的方式返回LDAP结果?

本文关键字:浏览 允许我 一种 结果 LDAP 返回 方式 net DirectorySearch 是否 | 更新日期: 2023-09-27 18:10:41

我正在c#中工作,并且正在尝试使用DirectorySearch来查询一个非常大的Microsoft ActiveDirectory LDAP服务器的组。

因此,在我的应用程序中,我将有一个组的分页列表,具有搜索功能。当然,我不希望每次点击"下一页"时都将这些查询的整个结果集传递给LDAP服务器。

是否有一种方法,使用DirectorySearch,只检索单个任意页面的结果,而不是在一个方法调用中返回整个结果集?

相似的问题:

  • DirectorySearch。
  • c# Active Directory Services findAll()只返回1000个条目

存在许多这样的问题,当有人询问分页(从LDAP服务器到应用服务器)时,得到的回答涉及PageSize和SizeLimit。然而,这些属性只影响c#服务器和LDAP服务器之间的分页,最后,DirectorySearch仅有的相关方法是FindOne()和FindAll()。

我要找的基本上是"findpage (pageSize, pageNumber)"(页码是真正重要的位。我不只是想要前1000个结果,我还想要(例如)1000个结果中的第100个集合。应用程序不能等待100,000条记录从LDAP服务器传递到应用程序服务器,即使它们被分解成1,000条记录块。

我理解DirectoryServices。协议有SearchRequest,它(我认为?)允许您使用"PageResultRequestControl",它看起来像我正在寻找的东西(尽管它看起来像分页信息来自"cookie",我不确定我应该如何检索)。但是如果有一种方法可以做到这一点,而不用重写整个东西来使用协议,我宁愿不这样做。

我只是无法想象没有办法做到这一点…SQL也有Row_Number

更新:PageResultRequestControl没有帮助-它是向前的和顺序的(你必须调用并获得前N个结果之前,你可以获得必要的"cookie"令牌进行调用,以获得结果N+1)。

然而,cookie似乎有某种可重复的排序…对于我正在处理的一个结果集,我逐一遍历结果,每次得到的cookie如下:

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

当我对2乘2进行迭代时,我得到了相同的数字(11,16)。这让我想到,如果我能弄清楚这些数字是如何生成的代码,我就可以创建一个ad-hoc cookie,它将为我提供我正在寻找的分页。

在.net 4.0中,DirectorySearch是否可以以一种允许我浏览它们的方式返回LDAP结果?

PageResultRequestControl确实是这样做的,它是LDAP协议的一部分。你只需要弄清楚这对你的代码意味着什么,抱歉。应该有一种方法可以在您所在的地方使用它,但是,话虽如此,我在Java中工作,并且我刚刚不得不编写了一打左右的请求控件和扩展操作类来使用JNDI,所以您可能不太幸运……否则你就得像我一样。警告,ASN.1解析紧跟其后:-|

遗憾的是,鉴于目前的c#库,似乎没有办法做到这一点。

所有标准c# 4.0 LDAP库都返回Top-N结果(如FindAll(),它返回每个结果,FindOne(),它返回第一个结果,或SearchResult与PageResultRequestControl,它返回结果N到N+M,但需要您检索结果1到N-1之前,您将有一个cookie令牌,您可以通过请求传递以获得下一个集合。

我还没有找到任何第三方LDAP库允许这样做。

除非找到更好的解决方案,否则我的前进道路将是修改界面,以显示前X个结果,而不具有客户端分页功能(显然仍然使用服务器端分页)。

我可能会在以后的日期追求只向前的分页系统,通过将更新的cookie与响应一起传递给客户端,并通过单击"More Results"类型的按钮将其传递回来。不管这些饼干是否可以手工制作,这可能值得以后再研究。

更新:我与Microsoft Support进行了交谈,并确认了这一点——没有办法对LDAP服务器进行动态分页。这是LDAP服务器自身的限制。

您可以随意使用Protocols和Paging控件(如果您的LDAP服务器支持的话)向前推进,但是对于cookie没有跨服务器(甚至是跨版本)的标准,因此您不能合理地制作自己的标准,也不能保证cookie可以被重复查询重用。

一个完整的解决方案包括使用协议(如上所述的分页)将可分页的结果集拉入SQL,无论是放入临时表还是永久存储表,并允许用户以传统方式对结果集进行分页和排序。请记住,您的结果不会完全是最新的,但是通过一些智能缓存更新,您可以将这种风险降到最低。

也许您想使用range-attribute来迭代您的"pages":

——复制,粘贴——

此示例检索0-500项(包括)。

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

——复制,粘贴——

更多信息参见:

枚举大型组中的成员https://msdn.microsoft.com/en-us/library/ms180907.aspx

属性值范围检索https://msdn.microsoft.com/en-us/library/cc223242.aspx

使用范围检索进行搜索https://msdn.microsoft.com/en-us/library/aa367017.aspx