SharePoint Boss

Benvenuti nel mio blog
posts - 13, comments - 589, trackbacks - 3

lunedì 28 ottobre 2013

Sharepoint Saturday Italy on tour @Rome

Con grande piacere annunciamo che lo SharePoint Saturday Italy riparte il 25 Gennaio 2014 da Roma. Avremo a disposizione una mega sala con una capienza di più di 130 persone e da oggi parte la call for speaker che rimarrà aperta fino al 11/11 alle ore 11:11. Le info per sottomettere la propria sessione le trovate sul sito o direttamente qui http://www.emailmeform.com/builder/form/cd05b33I8GZK7YN1w Segui tutti gli aggiornamenti sulla pagina facebook: https://www.facebook.com/SharepointSaturdayItaly?hc_location=stream

posted @ lunedì 28 ottobre 2013 11:07 | Filed Under [ PowerShell .NET SharePoint 2013 ]

martedì 21 febbraio 2012

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.

posted @ martedì 21 febbraio 2012 15:52 | Feedback (2446) | Filed Under [ SharePoint 2010 ]

martedì 7 febbraio 2012

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[];

posted @ martedì 7 febbraio 2012 23:24 | Feedback (144) | Filed Under [ SharePoint 2010 .NET Framework 3.5 ]

martedì 13 dicembre 2011

SPQuery: count items

Per recuperare il numero degli items di una lists per una determinata Query, eventualmente creata a run time, la sintassi base che uno scriverebbe è la seguente:

int ItemCount;

SPQuery query = new SPQuery();

query.Query = view.Query;

ItemCount = list.GetItems(query).Count;

da questo snippet ho omesso il RowLimit perchè altrimenti non avrei una Count valida, supponendo di creare un paginatore.

Ma qui ho riscontrato un enorme problema, i tempi di risposta, perchè il GetItems anche se alla fine richiediamo il Count comunque restituisce tutti gli items e poi ritorna il totale, ho notato che già con 3000 items i tempi di attesa si aggirano sui 10/14 secondi (un botto!!!).

La soluzione è banalissima, comunque siamo costretti a fare il GetItems, ma considerato che abbiamo necessità solo di una Count cerchiamo di minimizzare il tutto e quindi nella mia query specificherò che i ViewFields dovranno essere solamente 1 cioè l'ID (numerico), quindi insieme allo snippet di prima aggiungeremo anche:

1 query.ViewFields = "<FieldRef Name='ID' />";

Kid's stuff

posted @ martedì 13 dicembre 2011 18:47 | Feedback (92) |

venerdì 25 novembre 2011

Taxonomy & Custom Sort Order

Veramente banale gestire la visualizzazione dei termini di un Term Set di SharePoint, ma sono veramente insoddisfatto per come ho dovuto reperire il dato (sembra come se gli sviluppatori Microsoft andavano di corsa....), comunque, nel Term Store Management Tool della Central Administration dopo aver selezionato il gruppo e il Term Set sul pannello di destra compariranno i tabs come da figura:

Cliccando sul tab CUSTOM SORT si potranno assegnare le priorità di visualizzazione (assolutamente no!) desiderata per il vostro Term Set:

Perchè prima ho scritto e sottolineato "assolutamente no!"?

Perchè per reperire la lista dei termini con object model si utilizzerà questo codice:

TaxonomySession session = new TaxonomySession(site);
TermStore termstore = session.TermStores[TaxonomyUtils.TERM_STORE_NAME];
group = termstore.Groups.GetByName(TaxonomyUtils.TERM_GROUP);
termSets = group.TermSets[termSetName];

if (!string.IsNullOrEmpty(termSets.CustomSortOrder))
{
           string[] taxorder = termSets.CustomSortOrder.Split(':');
           foreach (var item in taxorder)
           {
                   Term oTerm = termSets.GetTerm(new Guid(item));
                   //...
            }
}
else
{
            foreach (var item in termSets.Terms)
            {
                  //....
             }
}

E fino qui, tutto ok, ma non c'è nessuna proprietà che mi permetta di indicare a SharePoint di prendere i termini ai quali ho applicato il Custom Sort Order e avere in output la stessa struttura dati, ma dovrò vedere se la stringa CustomSortOrder è diversa da null... e indovinate, se non è null avete la lista dei termini ma solamente nel formato Guid:Guid:Guid......

Mah...

Comunque alla fine quello che conta è che è stato un kid's stuff

posted @ venerdì 25 novembre 2011 21:33 | Feedback (21) |

giovedì 22 settembre 2011

Error occurred in deployment step ‘Activate Features’: The field with Id {field guid} defined in feature {feature guid} was found in the current site collection or in a subsite

Come risolvere questo errore?

Nel link http://tchmiel.wordpress.com/2010/08/09/activate-feature-error-custom-content-types-when-debugging-from-visual-studio-2010/ si possono trovare le istruzioni necessarie per far si che in fase di deploy non compaia l'errore in oggetto.

posted @ giovedì 22 settembre 2011 17:14 | Filed Under [ SharePoint 2010 ]

Abilitare la Developer Dashboard

Al fine di monitorare le performance del vostro lavoro su SharePoint dovrete necessariamente abilitare la Developer Dashboard, attraverso questo si potranno visualizzare tutte le attività inerenti l'elaborazione di pagina, oggetti, tempi di elaborazione e di output, niente male eh...

Per prima cosa bisognerà aprire la console di SharePoint 2010 Management Shell:

e incollare i seguenti comandi:

$svc=[Microsoft.SharePoint.Administration.SPWebService]::ContentService
$ddsetting=$svc.DeveloperDashboardSettings
$ddsetting.DisplayLevel=[Microsoft.SharePoint.Administration.SPDeveloperDashboardLevel]::OnDemand
$ddsetting.Update()

il risultato sarà:

posted @ giovedì 22 settembre 2011 17:13 | Filed Under [ PowerShell SharePoint 2010 ]

Attivazione di una Web Feature con Object Model

Per attivare una feature, che sia di SharePoint o creata dallo sviluppatore, attraverso object model basterà aprire il web nel quale si desidera l'attivazione e utilizzare il metodo Add dell'oggetto Features della variabile Web:

using (SPSite site = new SPSite("http://sito:8080")){
         using (SPWeb web = site.OpenWeb()){
                    web.Features.Add(new Guid("232f367b-33af-4fba-b560-e8a5e56e7ad7"), true);
          }
}

posted @ giovedì 22 settembre 2011 17:10 | Filed Under [ SharePoint 2010 .NET Framework 3.5 ]

Strumenti per l'Extension Manager di Visual Studio 2010 – Parte 2

Altro strumento molto simpatico da aggiungere nei tools di Visual Studio 2010 è devColor il quele inserirà su ogni pagina, css e oggetto di qualsiasi tipo ed estensione il colore che si sta utilizzando quando troverà un codice esadecimale (che normalmente viene usato per indicare colori) come per esempio su uno style:

 

inoltre tenendo premuto il tasto Ctrl verrà creata la toolbar contenente i colori che la vs pagina sta utilizzando, come in figura:

Non finisce qui...tenendo premuto Ctrl + click si aprirà la paletta con i colori per impostarne di nuovi:

posted @ giovedì 22 settembre 2011 17:09 | Filed Under [ Visual Studio 2010 .NET ]

Strumenti per l'Extension Manager di Visual Studio 2010 – Parte 1

Alcuni simpatici strumenti che potete, gratuitamente, installare su Visual Studio 2010 a supporto dello sviluppo di applicazioni SharePoint 2010 sono:

  • CSK - Development Tools Edition (Foundation - Server e WTC)
  • Mavention Activate Selected Features
  • Mavention SharePoint Project Item References

CSK - Development Tools Edition

Mavention

Mavention è molto comodo per ritrovare i vari oggetti di SharePoint che man mano si creano nella solution, per esempio web parts - content types - lists, che automaticamente Visual Studio 2010 associa alle features presenti.

Volendo è possibile configurarlo per evitare che alla creazione degli oggetti di SharePoint questi vengano associati automaticamente ad una feature.

posted @ giovedì 22 settembre 2011 17:06 | Filed Under [ Visual Studio 2010 .NET ]

Powered by:
Powered By Subtext Powered By ASP.NET