User Profile vs User Information List + Performance Test

Analizzando un aspetto interessante, sempre in ambito di sviluppi custom, inerente l'accesso alle informazioni personali degli utenti (DisplayName, Account Name, Picture, ecc.) ho messo a confronto l'uso del servizio User Profile e l'uso dell'oggetto SiteUserInfoList, vediamo il codice:

Utilizzo del servizio User Profile

 

SPServiceContext context = SPServiceContext.GetContext(site);
UserProfileManager objUserProfileManager = new UserProfileManager(context);
UserProfile profile = objUserProfileManager.GetUserProfile(LoginName);

string Title1 = profile.DisplayName;

 

Utilizzo dell'oggetto SiteUserInfoList

 

SPUser userinweb = web.EnsureUser(LoginName);
string Query = "<Where><Eq><FieldRef Name='ID' /><Value Type='Counter'>" + userinweb.ID + "</Value></Eq></Where>";
string ViewFields = "<FieldRef Name='Title' Nullable='TRUE' /><FieldRef Name='Picture' Nullable='TRUE' />";

SPQuery _query = new SPQuery();
_query.ViewFields = ViewFields;
_query.Query = Query;

SPListItem userItem = web.SiteUserInfoList.GetItems(_query)[0];

string Title2 = userItem["Title"].ToString();

 

Come si può notare, nel secondo caso, ho preferito utilizzare una CAML Query e quindi prendere il risulato con l'oggetto GetItems invece di usare il GetItemsById(userinweb.ID) perchè a livello di performance è più vantaggioso (strano ma vero) il primo metodo invece del secondo.

Ho chiamato questi due metodi, con un ciclo, per 100 volte e il risultato è stato: vince 7 a 0 l'oggetto SiteUserInfoList, a titolo di esempio i tempi che ho preso:

In questo link che ho trovato sulla rete si possono vedere tutti i campi che potranno essere interrogati per il SiteUserInfoList: 

http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/1c90abd0-54d7-482b-b16c-4c323bfbbd2c/

Il test l'ho eseguito in locale con un Notebook con processore i7, SSD e 8Gb di Ram, ma l'ho provato anche su una farm composta da 30 server (tipo NASA) e il risultato è stato che per la SiteUserInfoList la differenza tra il tempo finale e quello iniziale è pari a 0, mentre per il servizio User Profile rimane in termine di millesimi un leggero attimo di latenza.

Social Comments e Security Trimming

Eccomi qui a scrivere un bel post sui Commenti di SharePoint, che mi ha fatto tribolare per un pò ma che alla fine sono riuscito a svangarla (direi come al solito :P).

In un ambiente enterprise dove la security trimming è attivata potremmo avere qualche difficoltà con alcuni oggetti "social" di SharePoint, in particolare io mi sono scontrato con il metodo GetComments dell'oggetto SocialCommentManager, perchè? Perchè avevo la necessità di far visualizzare a livello pubblico i commenti inseriti su una determinata Uri dagli utenti della intranet che sto sviluppando. Il risultato era che sul mio ambiente di sviluppo, come al solito, tutto fila liscio, mentre una volta fatto il deploy dal cliente...succedeva che ogni utente vedeva i propri commenti :( azz!

Il seguente snippet riporta il modo con cui richiamavo il metodo GetComments:

 

SPWeb web = SPContext.Current.Web;
SPServiceContext context = SPServiceContext.Current;

Uri uri = new Uri(web.Url + pageUrl);

SocialCommentManager cm = new SocialCommentManager(context);
SocialComment[] commenti = cm.GetComments(uri);

 

Ma non finisce qui, dopo che ho certificato che il codice era giusto ma il risultato atteso non era esatto, provo con il web service di SharePoint e quindi altro snippet:

 

SocialDataService sds = new SocialDataService();
            Microsoft.Office.Server.SocialData.SocialDataService.SocialCommentDetail[] comments = sds.GetCommentsOnUrl(string.Concat(SPContext.Current.Site.Url, pageUrl), null, null, null);

 

Niente, sempre lo stesso risultato :(

Bene, disassembliamo e vediamo che cosa fanno i metodi e faccio una scoperta che mi lascia stupefatto. C'è un bel metodo INTERNAL ..... GetComments che accetta un parametro bool needSecurityTrim e ora?

 

Sia lodata la Reflection, con l'ultimo snippet potrete avere la soluzione ai vostri problemi, senza dover ricorrere a disabilitare il Security Trimming via PowerShell:

 

var type = typeof(SocialCommentManager);
            var methods = type.GetMethods(System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            var method = methods.FirstOrDefault(m => m.ToString() == "Microsoft.Office.Server.SocialData.SocialComment[] GetComments(System.Uri, Int32, Int32, System.DateTime, Boolean)");
            if (method == null) throw new MissingMethodException("Social GetComment method not found.");
            var comments = method.Invoke(cm, new object[] { uri, 10000, 0, DateTime.MinValue, false }) as SocialComment[];

 

Month List