LdapConnection SearchRequest 引发"The size limit was exceeded"异常



因为我们需要使用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);
}

在执行源代码时(我们已经使用外部第三方软件验证了凭据、主机、端口等),我们得到以下异常:

超出了大小限制

描述:在执行当前web请求期间发生未处理的异常。请查看堆栈跟踪以了解有关错误以及错误在代码中的来源的更多信息。

异常详细信息: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,TimeSpanrequestTimeOut,布尔异常OnTimeout)+2385System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequestrequest,TimeSpan requestTimeout)+499System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest请求)+50UserSearchProvider.ADUserSearchProvider.QueryStore(UserSearchCriteriaCollectioncriterias,Action1 logMessage) in c:UsersstemarieDocumentsVisual Studio 2012ProjectsIdealink.ModulesUserSearchProviderUserSearchProviderADUserSearchProvider.cs:298 UserSearchProvider.UserSearchProvider.QueryAndSort(UserSearchCriteriaCollection criterias, Action1 logMessage)演播室2012\Projects\Idealink.Modules\UserSearchProvider\UserSearchProvider。cs:77UserSearchProvider.UserSearchProvider.Search(UserSearchCriteriaCollectioncriterias,Action1 logMessage) in c:UsersstemarieDocumentsVisual Studio 2012ProjectsIdealink.ModulesUserSearchProviderUserSearchProviderUserSearchProvider.cs:33 UserSearchProvider.UserSearchService.Search(UserSearchCriteriaCollection criterias, Action1 logMessage)演播室2012\Projects\Idealink.Modules\UserSearchProvider\UserSearchService.cs:44UserSearchProviderTest_c:\Users\stemarie\Documents\Visual Studio中的默认.Page_Load(Object sender,EventArgs e)2012\Projects\Idealink.Modules\UserSearchProvider\UserSearchProvider Test\Default.aspx。cs:28

让我困惑的是,我们确实指定了最大大小限制,我们不希望超过100个条目-我们希望限制它。但是,即使我们指定了SizeLimit为1,库也会不断抛出错误。

有人对这个问题有什么见解/建议吗?我们离实现这一目标已经很近了,只需要解决最后一个问题。

您应该在类似的函数中使用cookie。该函数返回SearchResponse对象的集合,调用方应循环使用这些对象。

private List<SearchResponse> SearchDirectory(string distinguishedName, string searchFilter, System.DirectoryServices.Protocols.SearchScope searchScope, params string[] attributeList)
{
List<SearchResponse> result = new List<SearchResponse>();
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;
}

事实证明,这是有效的:

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

MSDN文档指出,您将获得一个DirectoryResponse类作为DirectoryOperationException.Response属性。但是,您可以将此属性强制转换为SearchResponse类型,然后使用SearchResponse.Entries属性来获取在达到指定SizeLimit之前收到的条目。

我已经尝试过了,我得到了预期的结果,我只是有点不高兴,因为我必须处理一个异常才能执行操作。

相关内容

最新更新