LdapConnection SearchRequest抛出“超出大小限制”的exception

由于我们需要使用LDAPS连接到LDAP服务器,因此我们必须使用LdapConnection而不是DirectoryEntry。

这是源代码:

SearchResponse response; using (LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(Host, Port))) { if (IsSSL) { con.SessionOptions.SecureSocketLayer = true; con.SessionOptions.VerifyServerCertificate = (connection, certificate) => true; } con.Credential = new NetworkCredential(_username, _password); con.AuthType = AuthType.Basic; con.Bind(); if (logMessage != null) logMessage("Connected to LDAP"); string sFilter = String.Format( "(&(objectcategory=person)(objectclass=user){0}(!(userAccountControl:1.2.840.113556.1.4.803:=2)))", filter ); SearchRequest request = new SearchRequest("OU=Corp,DC=mydc,DC=com", sFilter, SearchScope.Subtree); request.Attributes.Add(Resources.objectguid); request.Attributes.Add(Resources.givenname); request.Attributes.Add(Resources.sn); request.Attributes.Add(Resources.initials); request.Attributes.Add(Resources.samaccountname); request.Attributes.Add(Resources.userprincipalname); request.Attributes.Add(Resources.mail); request.Attributes.Add(Resources.objectsid); request.Attributes.Add(Resources.department); request.Attributes.Add(Resources.company); request.SizeLimit = 10; response = (SearchResponse) con.SendRequest(request); } 

执行源代码(我们使用外部第三方软件validation了凭据,主机,端口等)后,我们得到以下exception:

超出了大小限制

描述:执行当前Web请求期间发生未处理的exception。 请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

exception详细信息: System.DirectoryServices.Protocols.DirectoryOperationException:超出了大小限制

来源错误:

 response = (SearchResponse) con.SendRequest(request); 
 [DirectoryOperationException: The size limit was exceeded] System.DirectoryServices.Protocols.LdapConnection.ConstructResponse(Int32 

messageId,LdapOperation操作,ResultAll resultType,TimeSpan requestTimeOut,Boolean exceptionOnTimeOut)+2385 System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request,TimeSpan requestTimeout)+499 System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request)+50 UserSearchProvider .ADUserSearchProvider.QueryStore(UserSearchCriteriaCollection Criterias,Action 1 logMessage) in c:\Users\stemarie\Documents\Visual Studio 2012\Projects\Idealink.Modules\UserSearchProvider\UserSearchProvider\ADUserSearchProvider.cs:298 UserSearchProvider.UserSearchProvider.QueryAndSort(UserSearchCriteriaCollection criterias, Action 1 logMessage)在c:\ Users \ stemarie \ Documents \ Visual Studio 2012 \ Projects \ Idealink.Modules \ UserSearchProvider \ UserSearchProvider \ UserSearchProvider.cs:77 UserSearchProvider.UserSearchProvider.Search(UserSearchCriteriaCollection criterias,Action 1 logMessage) in c:\Users\stemarie\Documents\Visual Studio 2012\Projects\Idealink.Modules\UserSearchProvider\UserSearchProvider\UserSearchProvider.cs:33 UserSearchProvider.UserSearchService.Search(UserSearchCriteriaCollection criterias, Action 1 logMessage) in c:\Users\stemarie\Documents\Visual Studio 2012\Projects\Idealink.Modules\UserSearchProvider\UserSearchProvider\UserSearchProvider.cs:33 UserSearchProvider.UserSearchService.Search(UserSearchCriteriaCollection criterias, Action 1 logMessage)在c:\ Users \ stemarie \ Documents \ Visual Studio 2012 \ Projects \ Idealink.Modules \ UserSearchProvider \ UserSearchProvider \ UserSearchService.cs:44 UserSearchProviderTest._Default.Page_Load(Object sender,EventArgs e)位于c:\ Users \ stemarie \ Documents \ Visual Studio 2012 \ Projects \ Idealink.Modules \ UserSearchProvider \ UserSearchProviderTest \ Default.aspx.cs:28

困扰我的部分是我们确实指定了最大大小限制,我们不想要超过100个条目 – 我们想要限制它。 但即使我们指定SizeLimit为1,库也会一直抛出错误。

有没有人对此问题有任何见解/建议? 我们非常接近这个工作,只需解决最后一个问题。

您应该在与此类似的function中使用cookie。 该函数返回一个SearchResponse对象的集合,调用者应循环该对象。

 private List SearchDirectory(string distinguishedName, string searchFilter, System.DirectoryServices.Protocols.SearchScope searchScope, params string[] attributeList) { List result = new List(); SearchResponse response = null; int maxResultsToRequest = 100; try { PageResultRequestControl pageRequestControl = new PageResultRequestControl(maxResultsToRequest); // used to retrieve the cookie to send for the subsequent request PageResultResponseControl pageResponseControl; SearchRequest searchRequest = new SearchRequest(distinguishedName, searchFilter, searchScope, attributeList); searchRequest.Controls.Add(pageRequestControl); while (true) { response = (SearchResponse)connection.SendRequest(searchRequest); result.Add(response); pageResponseControl = (PageResultResponseControl)response.Controls[0]; if (pageResponseControl.Cookie.Length == 0) break; pageRequestControl.Cookie = pageResponseControl.Cookie; } } catch (Exception e) { // do something with the error } return result; } 

事实certificate,这有效:

  try { response = (SearchResponse)con.SendRequest(request); return response.Entries.Cast() .Select(entry => entry.Attributes) .Select(x => GetADUserSearchItemFromADProperties(x, logMessage)) .Where(user => user.HasName) .Cast(); } catch (DirectoryOperationException ex) { response = (SearchResponse) ex.Response; return response.Entries.Cast() .Select(entry => entry.Attributes) .Select(x => GetADUserSearchItemFromADProperties(x, logMessage)) .Where(user => user.HasName) .Cast(); } 

MSDN文档声明您将DirectoryResponse类作为DirectoryOperationException.Response属性获取。 但是,您可以将此属性强制转换为SearchResponse类型,然后使用SearchResponse.Entries属性获取在命中SizeLimit之前收到的条目。

我已经尝试了这个并且得到了预期的结果,我只是有点不高兴我必须处理exception才能执行操作。