Sí, el conjunto predeterminado de propiedades en UserPrincipal
es bastante limitado, pero la gran parte es: ¡existe una prolija historia de extensibilidad en su lugar!
Debe definir una clase que descienda de UserPrincipal
y luego podrá acceder fácilmente a muchas más propiedades, si es necesario.
El esqueleto sería algo como esto:
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);
}
}
}
Y eso es realmente casi todo lo que hay! Los métodos y ExtensionGet
ExtensionSet
le permiten "llegar a abajo" en la entrada de directorio subyacente y agarrar todos los atributos que le pueden interesar ....
Ahora, en su código, utiliza su nueva clase UserPrincipalEx
en lugar de 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;
}
}
Lea todo sobre el espacio de nombres System.DirectoryServices.AccountManagement
y su historia extensibilidad aquí:
Actualización: lo siento - aquí está la clase UserPrincipalExSearchFilter
- se perdió esa en la publicación original. Esto demuestra la capacidad de extender también los filtros de búsqueda, si es necesario:
public class UserPrincipalExSearchFilter : AdvancedFilters
{
public UserPrincipalExSearchFilter(Principal p) : base(p) { }
public void LogonCount(int value, MatchType mt)
{
this.AdvancedFilterSet("LogonCount", value, typeof(int), mt);
}
}
dónde viene este tipo (UserPrincipalExSearchFilter) viene? ¿Necesito crear este tipo usando el patrón de arriba? De hecho saqué esas pocas líneas de código y parece funcionar perfectamente (a menos que me falta algo). – Jay
@Jay: lo siento, mi mal, olvidé incluir esto. Actualizado mi respuesta. –
@ marc_s. Gracias por señalar el punto de extensibilidad (los métodos protegidos ExtensionGet/Set), creo que vale la pena mirar más de cerca a casa a veces !!) De todos modos, ¿conoce los problemas de seguridad/config necesarios para usar el objeto prinicpal derivado? He utilizado la subclase anterior y obtengo una excepción que dice "Los objetos principales de tipo UserPrincpalEx no se pueden usar para consultar esta tienda". ¿Algunas ideas? Gracias. – brumScouse