DirectorySearcher 分页查询LDAP数据

因需要从LDAP服务器获取客户的组织架构与人员信息,故对c#下获取轻目录数据做一个总结。

  1. 已知 客户LDAP服务器设置为每次最大查询1000条数据,组织机构数据共3111条
  2. 环境
  •         VS2010+.NET Framework 4
  •         引用System.DirectoryServices.dll以及System.DirectoryServices.Protocols.dll
  1. 选择方案
  •         DirectoryEntry+DirectorySearcher方式
  •         LDAPConnction+SearchRequest方式

    4.DirectoryEntry+DirectorySearcher方式

  •  连接服务器

/*构造LDAP的path*/

string path = string.Format("LDAP://{0}", domainName);

/*连接服务器,生成一个DirectoryEntry对象*/
DirectoryEntry domain = new DirectoryEntry(path,userName,userPwd,AuthenticationTypes.Secure);

  • 获取数据

/*在domain中查找到要查询的OU节点,并返回该节点的DirectoryEntry对象*/

DirectoryEntry needFindOU = domain.Children.Find("OU="+OUName);

/*根据上一步找到的节点DirectoryEntry对象以及要查询的filter条件,生成DirectorySearcher对象*/

DirectorySearcher mySearch = new DirectorySearcher(needFindOU,filter);

/*设置搜寻范围*/

mySearch.SearchScope = SearchScope.Subtree;

/*由于服务器做了返回数目限制,所以需要进行分页查询。因此设置DirectorySearcher的PageSize属性,以及SizeLimit属性。PageSize为分页搜索中的页大小的值,当其为0时表示不分页。SizeLimit为服务器在搜索中返回的最大对象数量的值,默认值为零,即表示使用由服务器确定的默认大小限制 1000 项。*/

mySearch.PageSize = 100;
mySearch.SizeLimit = 3000;

/*执行查询*/

SearchResultCollection coll = mySearch.FindAll();

/*

对上述PageSize以及SizeLimit多次测试:

pagesize sizelimit返回数据个数
100 1000 3111
100 60 60
100 100 100
100 101 3111

 

由此总结出当PageSize < SizeLimit 时可获取到所有数据。当PageSize>=SizeLimit时只能获取到由SizeLimit或服务器限制数目(SizeLimit与服务器限制谁小取谁)的数据。

*/

  • 释放占用资源,否则可能造成内存泄露,猜测会造成lsass.exe内存占用增大

执行 DirectoryEntry.Close();

执行 SearchResultCollection.Dispose();

/*MSDN上给出资料: The garbage collector does not release memory for a SearchResultCollection object.Therefore, you must call the Dispose method explicitly to prevent a memory leak.*/

 

    5.LDAPConnction+SearchRequest方式

此种方式没事显示分页获取数据,经查找多方资料并多次测试修改代码,没有成功获取到所有数据,只能获取到服务器限制的1000条数据。这里仍给出代码,希望能给人带来提示。有成功的小伙伴可以联系我,不胜感激。

 

  • 连接服务器

                NetworkCredential cre = new NetworkCredential(username, password);
                LdapConnection con = new LdapConnection(server);
                con.Credential = cre;
                con.AuthType = AuthType.Basic;
                con.Bind();

  • 获取数据

SearchRequest request = new SearchRequest(targetOu, filter, SearchScope.Subtree, null);
PageResultRequestControl page = new PageResultRequestControl(1001);
request.Controls.Add(page);

SearchResponse response = null;
                        try
                        {
                            response = (SearchResponse)con.SendRequest(request, timeOut);
                            if (response.Controls.Length > 0)
                            {
                                foreach (DirectoryControl col in response.Controls)
                                {
                                    if (col is PageResultResponseControl)
                                    {
                                        pageControl = col as PageResultResponseControl;
                                        break;
                                    }
                                }
                            }
                            data = response.Entries;
                            if (pageControl != null)
                            {
                                ((PageResultRequestControl)request.Controls[0]).Cookie = pageControl.Cookie;
                            }
                        }
                        catch (DirectoryOperationException ex)
                        {
                            response = (SearchResponse)ex.Response;
                            data = response.Entries;
                            if (response.Controls.Length > 0)
                            {
                                foreach (DirectoryControl col in response.Controls)
                                {
                                    if (col is PageResultResponseControl)
                                    {
                                        pageControl = col as PageResultResponseControl;
                                        break;
                                    }
                                }
                            }

                    }

  • 备注。经过测试发现SearchResponse.Control中返回的Control为0个。由此若做while循环执行(SearchResponse)con.SendRequest(request, timeOut);并根据返回response.Entries==null || response.Entries.Count==0来做退出条件,则会陷入死循环。因为它始终请求的是第一页的数据。

转载于:https://my.oschina.net/u/2551141/blog/1647586

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值