Background
J'ai récemment cherché à stocker des métadonnées concernant la fréquentation des utilisateurs sur une collection de site. Récupérer des données statistiques sur la fréquentation se fait à l'aide de la méthode GetUsageData() :
SPWeb.GetUsageData (SPUsageReportType, SPUsagePeriodType)
SPWeb.GetUsageData (SPUsageReportType, SPUsagePeriodType, Int32, DateTime)
Seulement voilà, cette méthode est propre à la classe SPWeb. Récupérer des statistiques globales au niveau du SPSite demande donc une agrégation de données en parcourant la liste des sites. Et dans ce cas, aller chercher toutes les données et les filtrer en temps réel n'est pas vraiment performant. J'ai donc choisi de réaliser un Job SharePoint afin d'agréger toutes les données la nuit, puis de les stocker quelque part... mais où ?
Problématique
Bien que ce ne soit pas l'option que j'ai retenue, j'ai tout d'abord pensé aux données utilisateurs déjà présentes sur la collection de site. Petit rappel : les sites SharePoint exposent des données relatives aux utilisateurs de ses sites. Ces données sont accessibles à l'aide du contrôle welcome.ascx placé sur la masterpage default.master.

Ce contrôle permet d'accéder à la page userdisp.aspx (du dossier SharePoint LAYOUTS) affichant les données concernant les utilisateurs.

Le lien avec le modèle objet semble évident, et j'imagine ne pas être le seul à penser instinctivement « SPUser ». Il m'est donc venu la question suivante : peut-on étendre la classe SPUser ?
L'enquête
Après avoir cherché un peu sur Internet et sur le MSDN, il apparait que non. Mais il me semblait pourtant bien avoir vue une structure différente de cette page sur deux environnements différents... et après vérification, il est bien possible d'avoir une structure différente pour décrire les utilisateurs.
J'ai donc investigué à l'aide de Reflector à partir de la classe UserDisplayPage (dont « hérite » la page UserDisplay.aspx) et je suis tombé sur cette ligne là :
this.UserListForm.ListId = base.Web.SiteUserInfoList.ID;
Et je m'en suis voulu de ne pas y avoir pensé plus tôt. Si vous avez parcouru les listes de vos sites avec le modèle objet, ou bien à l'aide d'un outil comme le CAML Query Builder ou un logiciel comme Access, vous avez surement du remarqué une List nommée « UserInfo »ou « Liste d'informations utilisateur ». Et c'est dans cette liste que sont stockées toutes les données affichées sur la page UserDisp.aspx.
Les tests
Un rapide test avec le modèle objet pour rajouter des champs :
SPFieldCollection fields = web.Lists["Liste d'informations utilisateur"].Fields;
fields.Add("URL du blog", SPFieldType.URL, false);
StringCollection choices = new StringCollection();
choices.Add("http://www.sharepointofview.fr/gat");
choices.Add("http://blogs.developpeur.org/phil");
choices.Add("http://blogs.developpeur.org/themit");
choices.Add("http://blogs.sharepointofview.fr/julien");
choices.Add("http://blogs.developpeur.org/fabrice69");
string fieldName = fields.Add("Blogosphere", SPFieldType.MultiChoice, false, true, choices);
Et voilà le résultat sur la page useredit.aspx :

... et sur la page userDisp.aspx

Conclusions
Bref, sans pour autant étendre un SPUser, la notion d'utilisateur de site est bien élargie. A noter toutefois :
- que la sécurité sur ces données utilisateur est basée sur celle des listes, donc pas nécessairement adaptée pour stocker du contenu personnel (pour cela, préférez les profils MOSS)
- que ces données sont propres à la collection de sites. La structure réservée aux données utilisateur reste donc différente dans les autres collections de site.
- que cette structure permet de stocker des pièces jointes.
Modifier la structure des données décrivant un SPUser se fait donc très simplement... il fallait juste y penser 