Inicio > .NET Framework, C#, Cómo hacer, SharePoint Foundation, Windows SharePoint Services > Cómo obtener todos los usuarios de un sitio

Cómo obtener todos los usuarios de un sitio


Si estás haciendo un desarrollo para SharePoint y de pronto quisieras saber cuáles son los usuarios que hay en un sitio, ¿qué hacer? Easy peasy. Comenzamos por referenciar nuestro Microsoft.SharePoint.dll de siempre e importamos el espacio de nombres Microsoft.SharePoint. Luego obtenemos un objeto SPWeb (ya sea mediante el SPContext.Current o creando un nuevo SPSite).

Si te das cuenta, SPWeb cuenta con al menos tres propiedades interesantes, todas las cuales regresan un objeto SPUserCollection (una colección de objetos SPUser), a saber:

    ¿Cuál es la diferencia entre estas tres propiedades? Pensando un poquito, SiteUsers salta a la vista y en efecto es lo que sospechas: esa propiedad regresa a todos los usuarios existentes en la colección de sitios. ¿Cuál será la diferencia entre las otras dos? Pues, en esencia, que Users te regresa todos los usuarios registrados en el sitio, mientras que AllUsers te regresa no nada más los usuarios registrados en el sitio, sino todos aquellos que hayan entrado al sitio alguna vez, o incluso que hayan sido referenciados en alguna lista (digamos, alguna alerta o algo por el estilo).

    Puede obtenerse un usuario específico por el índice de la colección, o bien por el nombre de usuario (de la forma “dominio\\nombreUsuario”), usando el indizador. O bien alguno de los métodos expuestos, como GetByID o GetByEmail.

    SPWeb web = SPContext.Current.Web;
    
    // propiedades de SPUser
    foreach (SPUser user in web.AllUsers)
    {
        string email = user.Email;
        string name = user.Name;
        // etc
    }
    
    // Obtener un usuario específico por correo electrónico
    SPUser user = web.AllUsers.GetByEmail("fernando.gomez@dominio.com");
    
    // Buscar todos los usuarios que comiencen con "Fer"
    var query = from SPUser user in web.AllUsers
                         where user.Name.BeginsWith("Fer")
                         select user;
    SPUser[] ferUsers = query.ToArray();
    
    // Easy Peasy
    

¿Y qué pasa si queremos consultar la información del perfil, desde un lugar fuera del servidor (i.e. una aplicación externa o desde Silverlight)? Pues usamos un servicio web, en concreto: UserGroup.asmx.

Este servicio web cuenta con tres métodos que te resultarán familiares:

  • UserGroup.GetAllUserCollectionFromWeb.
  • UserGroup.GetUserCollectionFromSite.
  • UserGroup.GetUserCollectionFromWeb.

¿Te suenan? Pues claro, son los equivalentes a SPWeb.AllUsers, SPWeb.SiteUsers y SPWeb.Users. Los métodos regresan un objeto tipo XmlNode, el cual contiene un XML más o menos con este esquema:

<GetUserCollectionFromWeb xmlns="http://schemas.microsoft.com/sharepoint/soap/directory/">
    <Users>
        <User ID="190" Sid="S-1-5-21-944133582-289434890-317593308-21562" 
            Name="Fernando Gómez" LoginName="dominio\fernando.gomez" 
            Email="fernando.gomez@dominio.com" Notes="" IsSiteAdmin="False" 
            IsDomainGroup="False" Flags="0" /> 
        <User ID="111" Sid="S-1-5-21-944133582-289434890-317593308-22617" 
            Name="Fulano De Tal" LoginName="dominio\fulano.detal" 
            Email="fulano.detal@dominio.com" Notes="" IsSiteAdmin="False" 
            IsDomainGroup="False" Flags="0" /> 
        <!-- etc -->
    </Users>
</GetUserCollectionFromWeb>

En esencia, el XML devuelto tiene un primer nodo, cuyo nombre corresponde al nombre del método (por ejemplo, de haber llamado a GetAllUserCollectionFromWeb, el nodo habría tenido este otro nombre), seguido de un nodo Users, el cuál contiene una colección de nodos User. Éstos últimos contienen atributos, cada uno representando información sobre el usuario. En el ejemplo te muesto algunos, como el ID interno, el nombre, la cuenta (LoginName) y el correo electrónico.

Cargar esta información, pues, es relativamente sencilla, dado que es el mismo esquema. Puedes cargarlo iterando sobre el nodo, o bien mediante LINQ to XML. Pero a mí me gusta usar XPath.

Es relativamente sencillo, de hecho, usar XPath. A primera instancia, puede que pienses en llamar a SelectNodes sobre el XmlNode, quizás algo así:

UserGroup service = new UserGroup();
service.Url = "http://labwf";
service.Credentials = CredentialCache.DefaultCredentials;

XmlNode rootNode =  service.GetAllUserCollectionFromWeb();
string xpath = "GetAllUserCollectionFromWeb/Users/descendant::User";
XmlNodeList nodes = rootNode.SelectNodes(xpath);
foreach (XmlNode node in nodes)
{
    string loginName = node.Attributes["LoginName"];
    string email = node.Attributes["Email"];
    // etc
}

service.Dispose();

Pero pues toma chango tu banano, lo anterior te regresará un XmlNodeList vacío. La razón es que el XML devuelto por el servicio web contiene un espacio de nombres especificado. Pero no uno cualquiera, sino el que se usa por default: xmlns.

Para solventar este problema tenemos que llamar SelectNodes con un gestionador de espacio de nombres (XmlNamespaceManager), al cual le añadiremos el espacio de nombres que viene en el XML junto con un prefijo con el que lo queramos identificar (en mi caso, he escogido “defns”). Pero el gestionador necesita de una tabla de nombres en su constructor, y la forma más sencilla de obtenerla, según pude ver, es crear un XmlDocument y usar su propiedad NameTable.

Una vez hecho esto, podremos usar el SelectNodes sober el XmlDocument, pero tendremos que cambier el XPath para que referencie el prefijo que añadimos al gestionador de espacios de nombres. Por ejemplo, en mi caso, el XPath quedaría como:

defns:GetAllUserCollectionFromWeb/defns:Users/descendant::defns:User

Así luciría nuestro código.

// preparar el servicio web
UserGroup service = new UserGroup();
service.Url = "http://labwf";
service.Credentials = CredentialCache.DefaultCredentials;

// generar el documento xml con los usuarios
XmlNode rootNode =  service.GetAllUserCollectionFromWeb();
XmlDocument doc = new XmlDocument();
doc.LoadXml(rootNode.OuterXml);

// crear el gestionador de espacios de nombres 
XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
manager.AddNamespace("defns", "http://schemas.microsoft.com/sharepoint/soap/directory/");

// ejecutar nuestro xpath...
string xpath = "defns:GetAllUserCollectionFromWeb/defns:Users/descendant::defns:User";
XmlNodeList nodes = rootNode.SelectNodes(xpath);

//... y ahora sí iterar sobre los resultados
foreach (XmlNode node in nodes)
{
    string loginName = node.Attributes["LoginName"];
    string email = node.Attributes["Email"];
    // etc
}

service.Dispose();

Bien, pues eso es todo por el momento. Ya veremos más cosas de usuarios en el siguiente post…

Anuncios
  1. Aún no hay comentarios.
  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s