2012-11-26 6 views
6

LDAPS kullanarak bir LDAP sunucusuna bağlanmamız gerektiğinden, DirectoryEntry yerine LdapConnection kullanmamız gerekir. İşte LdapConnection SearchRequest, "Boyut sınırı aşıldı" için istisna atar

kaynak kodu:

kaynak kodunun yürütülmesi (biz vb kimlik bilgilerini, ev sahibi, liman, doğruladıktan - Harici 3. parti yazılım kullanarak) üzerine
 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); 
     } 

aşağıdaki istisna olsun:

boyut sınırı

Açıklama aşıldı: işlenmemiş özel durum geçerli web isteği yürütülürken oluştu. Hata hakkında ve kodda nereden kaynaklandığı hakkında daha fazla bilgi için yığın izlemesini gözden geçirin.

durum ayrıntıları: System.DirectoryServices.Protocols.DirectoryOperationException: boyut sınırı

aşıldı

Kaynak hatası:

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

messageId, LdapOperation operation, 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) in 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\UserSearchService.cs:44 UserSearchProviderTest._Default.Page_Load(Object sender, EventArgs e) in c:\Users\stemarie\Documents\Visual Studio 2012\Projects\Idealink.Modules\UserSearchProvider\UserSearchProviderTest\Default.aspx.cs:28

beni karıştırır kısmı yaptığımız olmasıdır Maksimum boyut sınırını belirtin, 100'den fazla giriş istemiyoruz - sınırlamak istiyoruz. Fakat yine de, bir BOXLIMIT değeri belirtsek bile kitaplık sürekli olarak hata atar. 0

Bu sorunla ilgili herhangi bir fikir/öneri var mı? Bu çalışmaya başlamaya çok yakınız ve sadece bu son sorunu çözmeliyiz. Sonradan anlaşıldı ki

+0

Aramanızla eşleşen dizin girişi sayısı nedir? SizeLimit satırını kaldırırsanız ne olur? Değeri sunucu sayfa boyutundan daha düşük olduğunda, sizelimit başarısız olur. Sanırım sayfalanmış bir arama yayınlamayı denemelisiniz, bkz. Http://stackoverflow.com/q/1646518/1236044 – jbl

+0

İstekte sayfalanmış bir arama denetimi yaptım ancak sunucunun disk belleği aramayı desteklemediği yönünde bir yanıt aldım. –

+0

Aramamla kaç tane giriş yapılabileceğini bilmiyorum, ama sadece 100 tane istiyorum. Kodun amacı, ürünümüz için LDAPS'de "kullanıcı aramalarını" gerçekleştiren bir bileşen oluşturmaktır - Bu kitaplık bir frankenlibrary değil - biz de sunabileceğimiz çok sağlam bir LDAPS kullanıcı araması (adaptör kalıbı) kitaplığı olmasını istiyoruz Bu müşterilerimize. Bu yüzden, kullanıcı girdisini tahmin etmenin ve kitaplık için bunun ne anlama gelebileceğini tahmin etmenin bir yolu yok. –

cevap

1

, bu çalışır: DirectoryOperationException.Response özelliği olarak bir DirectoryResponse sınıf olsun

  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 belgelerine durumları. Ancak bu özelliği SearchResponse türüne yayınlayabilir ve daha sonra belirtilen SizeLimit'e ulaşmadan önce aldığınız girdileri almak için SearchResponse.Entries özelliğini kullanabilirsiniz.

Bunu denedim ve beklenen sonuçları aldığımda, işlemi gerçekleştirmek için bir istisna ile çalışmak zorunda kaldığım için biraz üzgünüm.

+2

Bu çözümle ilgili bir problem, bence, * tüm * arama yanıtlarını, sadece SizeLimit'e kadar olan yanıtları almamanızdır. Daha doğru bir çözüm, Ex.Response'den aldığınız yanıtları ayıklamak, ardından SendRequest'i yeniden çalıştırmak ancak bir şekilde henüz almadığınız şeyleri kapsamını sınırlandırmak olacaktır. – Irinotecan

6

Çerezleri buna benzer bir işlevde kullanmalısınız. Bu işlev, arayan kişinin döngü yapması gereken bir SearchResponse nesnesi koleksiyonu döndürür.

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