2012-11-26 10 views
6

इस तथ्य के कारण कि हमें एलडीएपीएस का उपयोग करके एलडीएपी सर्वर से कनेक्ट करने की आवश्यकता है, हमें DirectoryEntry के बजाय LdapConnection का उपयोग करना होगा।LdapConnection SearchRequest "आकार सीमा पार हो गई" के लिए अपवाद फेंकता है

यहाँ स्रोत कोड है:

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

स्रोत कोड के निष्पादन (हम साख, मेजबान, बंदरगाह, आदि का सत्यापन किया है - एक बाहरी 3 पार्टी सॉफ्टवेयर का उपयोग कर) पर हम निम्न अपवाद प्राप्त करें:

आकार की सीमा पार कर गया था

विवरण: वर्तमान वेब अनुरोध के निष्पादन के दौरान एक बिना क्रिया का अपवाद हो गई। त्रुटि के बारे में अधिक जानकारी के लिए और जहां यह कोड में उत्पन्न हुआ, कृपया स्टैक ट्रेस की समीक्षा करें।

अपवाद विवरण: System.DirectoryServices.Protocols.DirectoryOperationException: आकार सीमा

पार कर गया था

स्रोत त्रुटि:

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

बात यह है कि मुझे confuses कि हमने किया है अधिकतम आकार सीमा निर्दिष्ट करें, हम 100 से अधिक प्रविष्टियों को नहीं चाहते हैं - हम इसे सीमित करना चाहते हैं। लेकिन फिर भी लाइब्रेरी लगातार त्रुटि को फेंकता है भले ही हम आकार का आकार 1.

क्या किसी के पास इस मुद्दे के बारे में कोई अंतर्दृष्टि/सुझाव है? हम इस काम को पाने के बहुत करीब हैं और इस अंतिम समस्या को हल करने की आवश्यकता है।

+0

आपकी निर्देशिका से कितनी निर्देशिका प्रविष्टियां मेल खाते हैं? यदि आप SizeLimit लाइन को हटाते हैं तो क्या होता है? लगता है कि sizelimit विफल हो जाएगा यदि इसका मान सर्वर पेज आकार से कम है। मुझे लगता है कि आपको एक पेजेड खोज जारी करने का प्रयास करना चाहिए http://stackoverflow.com/q/1646518/1236044 – jbl

+0

मैंने अनुरोध में एक पेजेड खोज नियंत्रण जारी किया लेकिन प्रतिक्रिया मिली कि सर्वर पेजेड खोज का समर्थन नहीं करता है। –

+0

मुझे नहीं पता कि मेरी खोज से कितनी प्रविष्टियां मिल सकती हैं, लेकिन मुझे केवल उनमें से 100 चाहिए। कोड का उद्देश्य एक ऐसा घटक बनाना है जो हमारे उत्पाद के लिए एलडीएपीएस में "उपयोगकर्ता खोज" करता है - यह लाइब्रेरी फ्रैंकलिन लाइब्रेरी नहीं है - हम चाहते हैं कि यह एक बहुत ही मजबूत एलडीएपीएस उपयोगकर्ता खोज (एडाप्टर पैटर्न) लाइब्रेरी हो ताकि हम पेशकश कर सकें यह हमारे ग्राहकों के लिए है। तो मेरे पास उपयोगकर्ता इनपुट की भविष्यवाणी करने का कोई तरीका नहीं है और लाइब्रेरी के लिए इसका कितना परिणाम हो सकता है। –

उत्तर

1

यह पता चला है के रूप में, यह काम करता है:

  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 प्रलेखीकरण कहा गया है कि आप DirectoryOperationException.Response संपत्ति के रूप में एक DirectoryResponse वर्ग मिलता है। हालांकि आप इस संपत्ति को SearchResponse प्रकार पर डाल सकते हैं और फिर निर्दिष्ट आकार सीमा को मारने से पहले प्राप्त प्रविष्टियों को प्राप्त करने के लिए SearchResponse.Entries प्रॉपर्टी का उपयोग कर सकते हैं।

मैंने यह कोशिश की है और मुझे अपेक्षित परिणाम मिलते हैं, मैं थोड़ा परेशान हूं कि मुझे ऑपरेशन करने के लिए अपवाद के साथ काम करना है।

+2

मुझे लगता है कि इस समाधान के साथ एक समस्या यह है कि आपको * सभी * खोज प्रतिक्रियाएं नहीं मिलती हैं, केवल आकार लिमिट तक प्रतिक्रियाएं होती हैं। Ex.Response से प्राप्त प्रतिक्रियाओं को निकालने का एक और सही समाधान होगा, फिर SendRequest को फिर से चलाएं लेकिन किसी भी तरह से उस दायरे को सीमित कर दें जिसे आपने अभी तक पुनर्प्राप्त नहीं किया है ... – Irinotecan

6

आपको इसी तरह के फ़ंक्शन में कुकीज़ का उपयोग करना चाहिए। फ़ंक्शन 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; 
} 
संबंधित मुद्दे