Расширенные принципы пользователя C#
Моя организация использует комбинацию AD и LDS. AD синхронизируется с LDS и сохраняет некоторую информацию в полях extensionAttribute [в основном, 10, 11 и 12].
Я могу получить стандартную информацию в порядке от LDS, то есть Title, Surname, Initials, но не могу получить exntensionAttributes. Я использовал этот пример для расширения UserPrincipal, но все еще не могу увидеть значения атрибута.
[DirectoryRdnPrefix("CN")]
[DirectoryObjectClass("user")]
public class UserPrincipalEx : UserPrincipal
{
public UserPrincipalEx(PrincipalContext context)
: base(context)
{ }
public UserPrincipalEx(PrincipalContext context, string samAccountName, string password, bool enabled)
:base(context, samAccountName,password,enabled)
{ }
public static new UserPrincipalEx FindByIdentity(PrincipalContext context, string identityValue)
{
return (UserPrincipalEx)FindByIdentityWithType(context, typeof(UserPrincipalEx), identityValue);
}
public static new UserPrincipalEx FindByIdentity(PrincipalContext context, IdentityType identityType, string identityValue)
{
return (UserPrincipalEx)FindByIdentityWithType(context, typeof(UserPrincipalEx), identityType, identityValue);
}
[DirectoryProperty("extensionAttribute10")]
public string Ext10
{
get
{
if (ExtensionGet("extensionAttribute10").Length != 1)
return null;
return (string)ExtensionGet("extensionAttribute10")[0];
}
}
}
Тогда у меня есть:
PrincipalContext ctx = new PrincipalContext(ContextType.ApplicationDirectory, "LDSServerHere:389", "OU HERE", "Acccount Name Here", "Password HEre");
UserPrincipalEx u = UserPrincipalEx.FindByIdentity(ctx, IdentityType.SamAccountName, login);
string prop = string.Empty;
try
{
prop = u.Ext10;
}
catch (Exception ex)
{
prop = ex.ToString();
}
return prop;
Продолжайте получать исключение NULLReferenceException: ссылка на объект не установлена на экземпляр объекта
Я делаю что-то глупое здесь?
1 ответ
Призвание FindByIdentityWithType
не сработает Глядя на документацию, она унаследована от Principal
(не UserPrincipal
) и он говорит, что "не предназначен для вызова непосредственно из вашего кода". Скорее всего, он просто не понимает ваш производный класс, поэтому ничего не возвращает, потому что ничего не находит в вашем классе.
Но есть и другой способ сделать это: использовать DirectoryEntry
,
PrincipalContext ctx = new PrincipalContext(ContextType.ApplicationDirectory, "LDSServerHere:389", "OU HERE", "Acccount Name Here", "Password HEre");
UserPrincipal u = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, login);
string prop = string.Empty;
try
{
var de = (DirectoryEntry) u.GetUnderlyingObject();
if (de.Properties.Contains("extensionAttribute10")) {
prop = de.Properties["extensionAttribute10"].Value;
}
}
catch (Exception ex)
{
prop = ex.ToString();
}
return prop;
Обратите внимание на нулевую проверку свойства. Если атрибут пуст, он не будет существовать в Properties
Коллекция на всех. Вы могли бы, вероятно, добавить туда несколько дополнительных нулевых проверок просто для безопасности.
UserPrincipal
и другие занятия в AccountManagement
Пространство имен просто использовать DirectoryEntry
на заднем плане в любом случае. Они просто не раскрывают все доступные атрибуты. Так что иногда вы должны использовать DirectoryEntry
непосредственно.
На самом деле, я обнаружил, что гораздо быстрее и эффективнее использовать только DirectoryEntry
и не использовать AccountManagement
пространство имен вообще, хотя иногда это может быть немного сложнее в использовании.