在.Net 4.0中,DirectorySearch能否以允许我翻阅它们的方式返回LDAP结果?

我正在使用C#,并且正在尝试使用DirectorySearch查询极大的Microsoft ActiveDirectory LDAP服务器的组。

因此,在我的应用程序中,我将有一个具有搜索function的分组列表。 当然,每次点击“下一页”时,我都不想通过向我传递这些查询的整个结果集来敲击我的LDAP服务器。

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

类似的问题:

  • DirectorySearch.PageSize = 2不起作用
  • c #Active Directory服务findAll()仅返回1000个条目

存在许多这样的问题,其中有人询问分页(意味着从LDAP服务器到应用服务器),并获得涉及PageSize和SizeLimit的响应。 但是,这些属性仅影响C#服务器和LDAP服务器之间的分页,最后,DirectorySearch唯一相关的方法是FindOne()和FindAll()。

我正在寻找的基本上是“FindPaged(pageSize,pageNumber)”(pageNumber是非常重要的一点。我不只是想要前1000个结果,我想要(例如)第100集1000个结果。应用程序不能等待100,000条记录从LDAP服务器传递到应用服务器,即使它们被分解为1,000条记录块。

我知道DirectoryServices.Protocols有SearchRequest,它(我认为?)允许你使用“PageResultRequestControl”,它看起来像我正在寻找的东西(虽然它看起来像分页信息来自“cookies”,我不确定我应该如何检索)。 但是,如果有一种方法可以做到这一点,而不是重写整个事物而不是使用协议,我宁愿不必这样做。

我无法想象没有办法做到这一点……甚至SQL都有Row_Number。

更新:PageResultRequestControl没有帮助 – 它只是向前和顺序(您必须调用并获得前N个结果,然后才能获得调用获得结果N + 1所需的“cookie”标记)。

但是,cookie看起来确实有某种可重复的排序……在我正在研究的结果集上,我逐个遍历结果,每次cookie都出现了:

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

当我迭代两次,我得到相同的数字(11,16)。 这让我觉得,如果我能弄清楚这些数字是如何生成的代码,我可以创建一个ad-hoc cookie,这将给我一个我正在寻找的分页。

PageResultRequestControl确实是这样做的方式,它是LDAP协议的一部分。 你只需要弄清楚你的代码意味着什么,抱歉。 应该有一种方法可以从你所处的位置使用它,但是,说到这里,我正在使用Java,我只需编写十几个请求控件和扩展操作类,以便与JNDI一起使用,所以你可能是运气不好……或者你可能不得不这样做。 警告,ASN.1解析紧随其后: – |

遗憾的是,考虑到当前的C#库,似乎没有办法做到这一点。

所有标准C#4.0 LDAP库都返回前N个结果(如,FindAll(),返回每个结果,FindOne()返回第一个结果,或者SearchResult返回PageResultRequestControl,返回结果N到N + M但要求您在获得可以传递请求的cookie令牌之前检索结果1到N-1,以获得下一组。

我也找不到允许这样做的任何第三方LDAP库。

除非找到更好的解决方案,否则我的前进方向是修改接口,而不是显示前X个结果,没有客户端分页function(显然仍然使用适当的服务器端分页)。

我可以通过将更新后的cookie传递给带有响应的客户端,并通过单击“更多结果”类型的按钮将其传回给我,从而在以后追求仅向前的寻呼系统。 无论这些cookies是否可以手工制作,以后都可能值得追求。

更新:我与Microsoft支持部门进行了交谈并确认了这一点 – 无法使用LDAP服务器进行动态分页。 这是LDAP服务器本身的限制。

您可以使用协议和分页控件(如果您的LDAP服务器支持它)随意前进,但cookie没有跨服务器(甚至跨版本)标准,因此您无法合理地制作自己的,并且无法保证cookie可以重复用于重复查询。

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

也许你想相应地使用range-attribute迭代你的“页面”:

– – 复制粘贴 – –

此示例检索条目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