我已成功使用AccountManagement代碼檢索基本的AD信息,但它僅返回關於返回對象的非常有限的一組信息。我如何使用AccountManagement功能從AD獲得擴展信息。具體來說,就像我在AD的實例中似乎要調用的職位或職位。使用System.DirectoryServices.AccountManagement獲取職位名稱
我知道如何使用舊的DirectoryServices來做到這一點,但我想知道如何使用新的名稱空間來做到這一點。
我已成功使用AccountManagement代碼檢索基本的AD信息,但它僅返回關於返回對象的非常有限的一組信息。我如何使用AccountManagement功能從AD獲得擴展信息。具體來說,就像我在AD的實例中似乎要調用的職位或職位。使用System.DirectoryServices.AccountManagement獲取職位名稱
我知道如何使用舊的DirectoryServices來做到這一點,但我想知道如何使用新的名稱空間來做到這一點。
是的,UserPrincipal
上的默認屬性集非常有限 - 但最重要的是:有一個簡潔的可擴展性故事!
您需要定義一個從UserPrincipal
降序的類,然後如果需要,您可以非常容易地訪問更多的屬性。
骨架會是這個樣子:
namespace ADExtended
{
[DirectoryRdnPrefix("CN")]
[DirectoryObjectClass("User")]
public class UserPrincipalEx : UserPrincipal
{
// Inplement the constructor using the base class constructor.
public UserPrincipalEx(PrincipalContext context) : base(context)
{ }
// Implement the constructor with initialization parameters.
public UserPrincipalEx(PrincipalContext context,
string samAccountName,
string password,
bool enabled) : base(context, samAccountName, password, enabled)
{}
UserPrincipalExSearchFilter searchFilter;
new public UserPrincipalExSearchFilter AdvancedSearchFilter
{
get
{
if (null == searchFilter)
searchFilter = new UserPrincipalExSearchFilter(this);
return searchFilter;
}
}
// Create the "Title" property.
[DirectoryProperty("title")]
public string Title
{
get
{
if (ExtensionGet("title").Length != 1)
return string.Empty;
return (string)ExtensionGet("title")[0];
}
set { ExtensionSet("title", value); }
}
// Implement the overloaded search method FindByIdentity.
public static new UserPrincipalEx FindByIdentity(PrincipalContext context, string identityValue)
{
return (UserPrincipalEx)FindByIdentityWithType(context, typeof(UserPrincipalEx), identityValue);
}
// Implement the overloaded search method FindByIdentity.
public static new UserPrincipalEx FindByIdentity(PrincipalContext context, IdentityType identityType, string identityValue)
{
return (UserPrincipalEx)FindByIdentityWithType(context, typeof(UserPrincipalEx), identityType, identityValue);
}
}
}
這就是真的,幾乎所有有!該ExtensionGet
和ExtensionSet
方法讓你「到達下」進入基本目錄條目,並抓住了所有的屬性,你可能會感興趣....
現在,在你的代碼,使用新的UserPrincipalEx
類,而不是UserPrincipal
:
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// Search the directory for the new object.
UserPrincipalEx myUser = UserPrincipalEx.FindByIdentity(ctx, "someUserName");
if(myUser != null)
{
// get the title which is now available on your "myUser" object!
string title = myUser.Title;
}
}
閱讀所有關於System.DirectoryServices.AccountManagement
命名空間和它的可擴展的故事在這裏:
更新:對不起 - 這裏的UserPrincipalExSearchFilter
類 - 錯過了原來的職位之一。它只是顯示了還可以擴展搜索過濾器的能力,如果需要的話:
public class UserPrincipalExSearchFilter : AdvancedFilters
{
public UserPrincipalExSearchFilter(Principal p) : base(p) { }
public void LogonCount(int value, MatchType mt)
{
this.AdvancedFilterSet("LogonCount", value, typeof(int), mt);
}
}
爲了擴大上述我敲了一個擴展方法來調用ExtensionGet。它使用反射來獲取您必須繼承的受保護方法。您可能需要使用這個,如果你是從Groups.Members返回UserPrincipalObjects,例如
public static class AccountManagmentExtensions
{
public static string ExtensionGet(this UserPrincipal up, string key)
{
string value = null;
MethodInfo mi = up.GetType()
.GetMethod("ExtensionGet", BindingFlags.NonPublic | BindingFlags.Instance);
Func<UserPrincipal, string, object[]> extensionGet = (k,v) =>
((object[])mi.Invoke(k, new object[] { v }));
if (extensionGet(up,key).Length > 0)
{
value = (string)extensionGet(up, key)[0];
}
return value;
}
}
+1這是非常方便的技巧。我就像「哦,現在我需要繼承!」你只是想了解這個方法是受保護的,並且設計爲通過子類訪問。我想起了一個話題我寫了一篇關於如何利用.NET反射來「突破」 OOP概念:http://mazdev.blogspot.ae/2011/05/breaching-object-oriented-programming.html – Mzn 2014-06-18 08:16:29
什麼價值的關鍵字不是字符串值。像'accountExpires'屬性中的'System._comObject'。 – 2016-11-01 21:04:11
哪裏該類型(UserPrincipalExSearchFilter)從何而來?我是否需要使用上述模式創建此類型?實際上,我將這幾行代碼拉出來,它看起來很完美(除非我錯過了某些東西)。 – Jay 2012-03-04 23:44:37
@Jay:對不起 - 我的不好 - 忘了包括這個。更新了我的回覆。 – 2012-03-05 05:51:54
@ marc_s。 Thankyou指出的可擴展性點(ExtensionGet/Set受保護的方法),我想它有時看起來更接近家庭!!)無論如何,你是否知道需要的安全問題/配置,使用派生的prinicpal對象。我已經實現了上面的子類並獲取了一個異常讀取「UserPrincpalEx類型的主體對象不能用於查詢這個商店」。有任何想法嗎?謝謝。 – brumScouse 2012-07-12 13:00:04