2009-11-25 45 views
2

我試圖通過LDAP查詢ActiveDirectory中,但是查詢可能會包含空格或其他字符可能導致問題的(連字符?)查詢Active Directory包含LDAP過濾器空間

(&(objectCategory=person)(objectClass=user)(|(&(sn=Bloggs*)(givenName=Jo*))(displayName=Jo Bloggs)) 

這是一個OR搜索例如在SQL這將是WHERE (sn LIKE 'Bloggs%' AND givenName LIKE 'Jo%') OR displayName = 'Jo Bloggs'

然而,當我嘗試LDAP查詢,我得到一個錯誤:System.ArgumentException: The (&(objectCategory=person)(objectClass=user)(|(&(sn=Bloggs*)(givenName=Jo*))(displayName=Jo Bloggs)) search filter is invalid

代碼進行搜索:

string userName = "Jo Bloggs"; 
DirectoryEntry adroot = new DirectoryEntry("LDAP://" + Environment.UserDomainName, "user", "password", AuthenticationTypes.Secure); 
DirectorySearcher search = new DirectorySearcher(adroot); 
search.Filter = string.Format("(&(objectCategory=person)(objectClass=user)(|(&(sn={0}*)(givenName={1}*))(displayName={2}))", userName.Split(' ')[1], userName.Split(' ')[0], userName); 

這僅僅是一個基本的搜索,我會喜歡搜索其他欄目(職位,電話,部門等),例如WHERE title LIKE '%foo%' OR telephonenumber LIKE '%foo% OR department LIKE '%foo%'

另外,我可以緩存搜索,所以ActiveDirectory不會從搜索同一事物的人那裏得到很多點擊嗎?

這也只能找到一個條目,我想搜索並顯示在中繼器中找到的所有結果。

+0

現在接受更多我以前的問題的答案。然而,還有一些沒有回答的問題(或者沒有答案(例如不能完成,系統限制),或者答案沒有完全回答這個問題) – SamWM

回答

2

你錯過了一個右括號。試試這個工作示例:

string userName = "Jo Bloggs"; 
string baseQuery = 
    "(&" + 
     "(objectCategory=person)" + 
     "(objectClass=user)" + 
     "(|" + 
      "(&" + 
       "(sn={0}*)" + 
       "(givenName={1}*)" + 
      ")" + 
      "(displayName={2})" + 
     ")" + 
    ")"; // <<< this is missing in your original query 

userName = Regex.Replace(userName, @"[\(\)\*\\]", (match) => 
       { // escape reserved chars 
        return "\\" + ((int)match.Value[0]).ToString("x"); 
       }, RegexOptions.Compiled); 
string query = String.Format(query, userName.Split(' ')[1], 
            userName.Split(' ')[0], userName); 
using (DirectoryEntry entry = new DirectoryEntry(
    "LDAP://" + Environment.UserDomainName, "user", "password", 
    AuthenticationTypes.Secure)) 
{ 
    using (DirectorySearcher ds = 
     new DirectorySearcher(entry, query, null, SearchScope.Subtree)) 
    { 
     SearchResultCollection res = ds.FindAll(); // all matches 
     if (res != null) 
      foreach (SearchResult r in res) 
       Console.WriteLine(user.Properties["displayName"].Value); 
    } 
} 

編輯:關於轉義序列,你應該參考這個文件:Creating a Query Filter。我編輯這個答案來反映這些信息。

If any of the following special characters must appear in the query filter as literals, they must be replaced by the listed escape sequence.

 
    ASCII  Escape sequence 
character  substitute 
    *   "\2a" 
    (   "\28" 
    )   "\29" 
    \   "\5c" 
    NUL   "\00" 

In addition, arbitrary binary data may be represented using the escape sequence syntax by encoding each byte of binary data with the backslash followed by two hexadecimal digits. For example, the four-byte value 0x00000004 is encoded as "\00\00\00\04" in a filter string.

+0

缺少支架是導致代碼不能正常工作......用你的方式寫入(分解成行),使得它更易於理解和調試 – SamWM

+0

如果displayName包含括號,例如'John Smith(PA to Director)'還是部門有'Finance&Performance'? – SamWM

+0

固定,請看看 –

0

也還有另一種LINQ到公元http://adlinq.codeplex.com框架,實現了多種IQueryable的擴展方法(單,首先,最後,SingleOrDefault等等)並且頻繁更新。