Reputation: 523
My organisation using a combination of AD and LDS. AD syncs to LDS and stores some information within the extensionAttribute fields [mainly 10, 11 and 12].
I can pull back the standard information okay from LDS, i.e. Title, Surname, Initials but can't get the exntensionAttributes.I have used the example to Extend the UserPrincipal but still am unable to see the attribute values.
[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];
}
}
}
I then have:
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;
Keep getting a NULLReferenceException: Object reference not set to an instance of an object
Am i doing something stupid here?
Upvotes: 0
Views: 680
Reputation: 41008
Calling FindByIdentityWithType
won't work. Looking at the documentation, it's inherited from Principal
(not UserPrincipal
) and it says it's "not intended to be called directly from your code". It likely just doesn't understand your derived class, so it's returning nothing because nothing it finds matches your class.
But there's another way to do it: use 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;
Notice the null check on the property. If the attribute is empty, it won't exist in the Properties
collection at all. You could probably add some extra null checks in there just to be safe.
UserPrincipal
and other classes in the AccountManagement
namespace just use DirectoryEntry
in the background anyway. They just don't expose all of the available attributes. So sometimes you have to use DirectoryEntry
directly.
Actually, I've found that it's much faster and more efficient to only use DirectoryEntry
and not use the AccountManagement
namespace at all, although it can be a little more complicated to use sometimes.
Upvotes: 1