2009-11-23 177 views

回答

79

其實,問題是如何得到兩個屬性的.NET 3.5 (System.DirectoryServices.AccountManagement.)UserPrincipal -object沒有給出userPrincipalName

這裏如何做到這一點與extension method

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using System.DirectoryServices; 
using System.DirectoryServices.AccountManagement; 

namespace MyExtensions 
{ 
    public static class AccountManagementExtensions 
    { 

     public static String GetProperty(this Principal principal, String property) 
     { 
      DirectoryEntry directoryEntry = principal.GetUnderlyingObject() as DirectoryEntry; 
      if (directoryEntry.Properties.Contains(property)) 
       return directoryEntry.Properties[property].Value.ToString(); 
      else 
       return String.Empty; 
     } 

     public static String GetCompany(this Principal principal) 
     { 
      return principal.GetProperty("company"); 
     } 

     public static String GetDepartment(this Principal principal) 
     { 
      return principal.GetProperty("department"); 
     } 

    } 
} 

上面的代碼將在大多數情況下(也就是將標準文字工作/字符串單值Active Directory屬性)。您需要修改代碼併爲您的環境添加更多錯誤處理代碼。

您可以使用它通過添加「擴展類」到您的項目,然後你可以這樣做:

PrincipalContext domain = new PrincipalContext(ContextType.Domain); 
UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(domain, "youruser"); 
Console.WriteLine(userPrincipal.GetCompany()); 
Console.WriteLine(userPrincipal.GetDepartment()); 
Console.WriteLine(userPrincipal.GetProperty("userAccountControl")); 

(順便說一句,這本來是爲擴展特性有很大用途 - too bad it won't be in C# 4 either。)

+1

您也可以查看Principal Extensions(http://msdn.microsoft.com/zh-cn/library/bb552835.aspx)以使用您需要的特定屬性創建自定義主體。 – 2009-11-24 09:07:11

+0

你會如何去做一個「設置」方法並保存一個值? – JustinStolle 2011-02-08 23:36:20

+0

@PerNoalt感謝您的代碼,但沒有一個簡短的方法直接從UserPrincipal直接獲取屬性,例如:部門,而不使用擴展? – Rama 2013-02-15 10:31:17

13

像這樣的東西應該這樣做,如果部門和公司屬性爲用戶存在。

DirectoryEntry de = new DirectoryEntry(); 
de.Path = "LDAP://dnsNameOfYourDC.my.company.com"; 
DirectorySearcher deSearch = new DirectorySearcher(de); 
deSearch.PropertiesToLoad.Add("department"); 
deSearch.PropertiesToLoad.Add("company"); 

deSearch.SearchScope = SearchScope.Subtree; 
deSearch.Filter = "(&(objectClass=User)(userPrincipalName=MyPrincipalName))"; 
SearchResultCollection results = deSearch.FindAll(): 

foreach (SearchResult result in results) 
{ 
    ResultPropertyCollection props = result.Properties; 
    foreach (string propName in props.PropertyNames) 
    { 
     //Loop properties and pick out company,department 
     string tmp = (string)props[propName][0]; 
    } 
} 
+2

一個小小的挑剔:在LDAP過濾器中,我寧願使用「objectCategory」而不是objectClass。爲什麼? objectCategory是單值的,並且在Active Directory中被索引,因此搜索者使用objectCategory更快。 – 2009-11-23 22:02:45

+2

實際上,如果您使用的是Windows Server 2008,則objectClass屬性默認會編入索引。如果您使用Windows Server 2000或2003,則不是。 – 2009-11-24 07:40:17

+0

這是一個很好的解決方案,因此非常感謝。我不得不在下面標記爲正確,但是我正在處理System.DirectoryServices.AccountManagement.UserPrincipal。 – wgpubs 2009-11-24 18:18:34

相關問題