SharePoint Boss http://blogs.ugidotnet.org/spboss/Default.aspx Benvenuti nel mio blog it Stefano Paterno Subtext Version 2.6.0.0 SharePoint Boss http://blogs.ugidotnet.org/images/RSS2Image.gif http://blogs.ugidotnet.org/spboss/Default.aspx 77 60 Sharepoint Saturday Italy on tour @Rome PowerShell .NET SharePoint 2013 http://blogs.ugidotnet.org/spboss/archive/2013/10/28/sharepoint-saturday-italy-on-tour-rome.aspx 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<img src="http://blogs.ugidotnet.org/spboss/aggbug/101706.aspx" width="1" height="1" /> Stefano Paterno http://blogs.ugidotnet.org/spboss/archive/2013/10/28/sharepoint-saturday-italy-on-tour-rome.aspx Mon, 28 Oct 2013 11:07:49 GMT http://blogs.ugidotnet.org/spboss/archive/2013/10/28/sharepoint-saturday-italy-on-tour-rome.aspx#feedback 1 http://blogs.ugidotnet.org/spboss/comments/commentRss/101706.aspx http://blogs.ugidotnet.org/spboss/services/trackbacks/101706.aspx User Profile vs User Information List + Performance Test SharePoint 2010 http://blogs.ugidotnet.org/spboss/archive/2012/02/21/user-profile-vs-user-information-list-performance-test.aspx <p>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:</p> <p><strong>Utilizzo del servizio User Profile</strong></p> <p>SPServiceContext context = SPServiceContext.GetContext(site); <br />            UserProfileManager objUserProfileManager = new UserProfileManager(context); <br />            UserProfile profile = objUserProfileManager.GetUserProfile(LoginName);</p> <p>            string Title1 = profile.DisplayName;</p> <p><code /></p> <p><strong>Utilizzo dell'oggetto SiteUserInfoList</strong></p> <p>SPUser userinweb = web.EnsureUser(LoginName); <br />            </p> <p>string Query = "&lt;Where&gt;&lt;Eq&gt;&lt;FieldRef Name='ID' /&gt;&lt;Value Type='Counter'&gt;" + userinweb.ID + "&lt;/Value&gt;&lt;/Eq&gt;&lt;/Where&gt;"; <br />            string ViewFields = "&lt;FieldRef Name='Title' Nullable='TRUE' /&gt;&lt;FieldRef Name='Picture' Nullable='TRUE' /&gt;";</p> <p>            SPQuery _query = new SPQuery(); <br />            _query.ViewFields = ViewFields; <br />            _query.Query = Query;</p> <p>            SPListItem userItem = web.SiteUserInfoList.GetItems(_query)[0];</p> <p>            string Title2 = userItem["Title"].ToString();</p> <p>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.</p> <p>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:</p> <p><img alt="" src="http://www.stefanopaterno.com/image.axd?picture=2012%2f2%2fTempi+UserProfile+e+SiteUserInfoList.PNG" /></p> <p>In questo link che ho trovato sulla rete si possono vedere tutti i campi che potranno essere interrogati per il SiteUserInfoList: </p> <p><a href="http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/1c90abd0-54d7-482b-b16c-4c323bfbbd2c/">http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/1c90abd0-54d7-482b-b16c-4c323bfbbd2c/</a></p> <p>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.</p><img src="http://blogs.ugidotnet.org/spboss/aggbug/100789.aspx" width="1" height="1" /> Stefano Paterno http://blogs.ugidotnet.org/spboss/archive/2012/02/21/user-profile-vs-user-information-list-performance-test.aspx Tue, 21 Feb 2012 15:52:43 GMT http://blogs.ugidotnet.org/spboss/archive/2012/02/21/user-profile-vs-user-information-list-performance-test.aspx#feedback 2446 http://blogs.ugidotnet.org/spboss/comments/commentRss/100789.aspx http://blogs.ugidotnet.org/spboss/services/trackbacks/100789.aspx Social Comments e Security Trimming .NET Framework 3.5 SharePoint 2010 http://blogs.ugidotnet.org/spboss/archive/2012/02/07/social-comments-e-security-trimming.aspx <p>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).</p> <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!</p> <p>Il seguente snippet riporta il modo con cui richiamavo il metodo GetComments:</p> <p><code>SPWeb web = SPContext.Current.Web;</code></p> <p><code>SPServiceContext context = SPServiceContext.Current;</code></p> <p><code>Uri uri = </code><code>new</code> <code>Uri(web.Url + pageUrl);</code></p> <p><code>SocialCommentManager cm = </code><code>new</code> <code>SocialCommentManager(context);</code></p> <p><code>SocialComment[] commenti = cm.GetComments(uri);</code></p> <p>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:</p> <p><code>SocialDataService sds = </code><code>new</code> <code>SocialDataService();</code></p> <p><code>Microsoft.Office.Server.SocialData.SocialDataService.SocialCommentDetail[] comments = sds.GetCommentsOnUrl(</code><code>string</code><code>.Concat(SPContext.Current.Site.Url, pageUrl), </code><code>null</code><code>, </code><code>null</code><code>, </code><code>null</code><code>);</code></p> <p>Niente, sempre lo stesso risultato :(</p> <p>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 <strong>needSecurityTrim</strong> e ora?</p> <p><img alt="" src="http://www.stefanopaterno.com/image.axd?picture=2012%2f2%2fSocialComments.PNG" width="900" /></p> <p>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:</p> <p><code>var type = </code><code>typeof</code><code>(SocialCommentManager);</code></p> <p><code>var methods = type.GetMethods(System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);</code></p> <p><code>var method = methods.FirstOrDefault(m =&gt; m.ToString() == </code><code>"Microsoft.Office.Server.SocialData.SocialComment[] GetComments(System.Uri, Int32, Int32, System.DateTime, Boolean)"</code><code>);</code></p> <p><code>if</code> <code>(method == </code><code>null</code><code>) </code><code>throw</code> <code>new</code> <code>MissingMethodException(</code><code>"Social GetComment method not found."</code><code>);</code></p> <p><code>var comments = method.Invoke(cm, </code><code>new</code> <code>object</code><code>[] { uri, 10000, 0, DateTime.MinValue, </code><code>false</code> <code>}) </code><code>as</code> <code>SocialComment[];</code></p><img src="http://blogs.ugidotnet.org/spboss/aggbug/100756.aspx" width="1" height="1" /> Stefano Paterno http://blogs.ugidotnet.org/spboss/archive/2012/02/07/social-comments-e-security-trimming.aspx Tue, 07 Feb 2012 23:24:01 GMT http://blogs.ugidotnet.org/spboss/archive/2012/02/07/social-comments-e-security-trimming.aspx#feedback 144 http://blogs.ugidotnet.org/spboss/comments/commentRss/100756.aspx http://blogs.ugidotnet.org/spboss/services/trackbacks/100756.aspx SPQuery: count items http://blogs.ugidotnet.org/spboss/archive/2011/12/13/spquery-count-items.aspx <p>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:</p> <p><code>int</code> <code>ItemCount;</code></p> <p><code>SPQuery query = </code><code>new</code> <code>SPQuery();</code></p> <p><code>query.Query = view.Query;</code></p> <p><code>ItemCount = list.GetItems(query).Count;</code></p> <p>da questo snippet ho omesso il RowLimit perchè altrimenti non avrei una Count valida, supponendo di creare un paginatore. </p> <p>Ma qui ho riscontrato un <strong>enorme </strong>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!!!).</p> <p>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:</p> <p><code>1 </code><code>query.ViewFields = </code><code>"&lt;FieldRef Name='ID' /&gt;"</code><code>;</code></p> <p>Kid's stuff</p><img src="http://blogs.ugidotnet.org/spboss/aggbug/100622.aspx" width="1" height="1" /> Stefano Paterno http://blogs.ugidotnet.org/spboss/archive/2011/12/13/spquery-count-items.aspx Tue, 13 Dec 2011 18:47:22 GMT http://blogs.ugidotnet.org/spboss/archive/2011/12/13/spquery-count-items.aspx#feedback 92 http://blogs.ugidotnet.org/spboss/comments/commentRss/100622.aspx http://blogs.ugidotnet.org/spboss/services/trackbacks/100622.aspx Taxonomy &amp; Custom Sort Order http://blogs.ugidotnet.org/spboss/archive/2011/11/25/taxonomy-amp-custom-sort-order.aspx <p>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:</p> <p><img alt="" src="http://www.stefanopaterno.com/image.axd?picture=2011%2f11%2fTax1.PNG" /></p> <p>Cliccando sul tab CUSTOM SORT si potranno assegnare le priorità di visualizzazione (assolutamente no!) desiderata per il vostro Term Set:</p> <p><img alt="" src="http://www.stefanopaterno.com/image.axd?picture=2011%2f11%2fTax2.PNG" /></p> <p>Perchè prima ho scritto e sottolineato "assolutamente no!"?</p> <p>Perchè per reperire la lista dei termini con object model si utilizzerà questo codice:</p> <p>TaxonomySession session = new TaxonomySession(site); <br />TermStore termstore = session.TermStores[TaxonomyUtils.TERM_STORE_NAME]; <br />group = termstore.Groups.GetByName(TaxonomyUtils.TERM_GROUP); <br />termSets = group.TermSets[termSetName];</p> <p>if (!string.IsNullOrEmpty(termSets.CustomSortOrder)) <br />{ <br />           string[] taxorder = termSets.CustomSortOrder.Split(':'); <br />           foreach (var item in taxorder) <br />           { <br />                   Term oTerm = termSets.GetTerm(new Guid(item)); <br />                   //... <br />            } <br />} <br />else <br />{ <br />            foreach (var item in termSets.Terms) <br />            { <br />                  //.... <br />             } <br />}</p> <p>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......</p> <p>Mah...</p> <p>Comunque alla fine quello che conta è che è stato un kid's stuff</p><img src="http://blogs.ugidotnet.org/spboss/aggbug/100559.aspx" width="1" height="1" /> Stefano Paterno http://blogs.ugidotnet.org/spboss/archive/2011/11/25/taxonomy-amp-custom-sort-order.aspx Fri, 25 Nov 2011 21:33:05 GMT http://blogs.ugidotnet.org/spboss/archive/2011/11/25/taxonomy-amp-custom-sort-order.aspx#feedback 21 http://blogs.ugidotnet.org/spboss/comments/commentRss/100559.aspx http://blogs.ugidotnet.org/spboss/services/trackbacks/100559.aspx Error occurred in deployment step &lsquo;Activate Features&rsquo;: The field with Id {field guid} defined in feature {feature guid} was found in the current site collection or in a subsite SharePoint 2010 http://blogs.ugidotnet.org/spboss/archive/2011/09/22/error-occurred-in-deployment-step-lsquoactivate-featuresrsquo-the-field-with.aspx <p>Come risolvere questo errore?</p> <p>Nel link <a href="http://tchmiel.wordpress.com/2010/08/09/activate-feature-error-custom-content-types-when-debugging-from-visual-studio-2010/">http://tchmiel.wordpress.com/2010/08/09/activate-feature-error-custom-content-types-when-debugging-from-visual-studio-2010/</a> si possono trovare le istruzioni necessarie per far si che in fase di deploy non compaia l'errore in oggetto.</p><img src="http://blogs.ugidotnet.org/spboss/aggbug/100383.aspx" width="1" height="1" /> Stefano Paterno http://blogs.ugidotnet.org/spboss/archive/2011/09/22/error-occurred-in-deployment-step-lsquoactivate-featuresrsquo-the-field-with.aspx Thu, 22 Sep 2011 17:14:36 GMT http://blogs.ugidotnet.org/spboss/archive/2011/09/22/error-occurred-in-deployment-step-lsquoactivate-featuresrsquo-the-field-with.aspx#feedback 3 http://blogs.ugidotnet.org/spboss/comments/commentRss/100383.aspx http://blogs.ugidotnet.org/spboss/services/trackbacks/100383.aspx Abilitare la Developer Dashboard PowerShell SharePoint 2010 http://blogs.ugidotnet.org/spboss/archive/2011/09/22/abilitare-la-developer-dashboard.aspx <p>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...</p> <p><img alt="" src="http://www.stefanopaterno.com/image.axd?picture=2011%2f8%2fDeveloperDashboard+part1.png" /></p> <p>Per prima cosa bisognerà aprire la console di SharePoint 2010 Management Shell:</p> <p><img alt="" src="http://www.stefanopaterno.com/image.axd?picture=2011%2f8%2fDeveloperDashboard+part3.png" /></p> <p>e incollare i seguenti comandi:</p> <pre class="csharpcode">$svc=[Microsoft.SharePoint.Administration.SPWebService]::ContentService $ddsetting=$svc.DeveloperDashboardSettings $ddsetting.DisplayLevel=[Microsoft.SharePoint.Administration.SPDeveloperDashboardLevel]::OnDemand $ddsetting.<span class="kwrd">Update</span>()</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p>il risultato sarà:</p> <p><img alt="" src="http://www.stefanopaterno.com/image.axd?picture=2011%2f8%2fDeveloperDashboard+part2.png" width="800" height="600" /></p><img src="http://blogs.ugidotnet.org/spboss/aggbug/100382.aspx" width="1" height="1" /> Stefano Paterno http://blogs.ugidotnet.org/spboss/archive/2011/09/22/abilitare-la-developer-dashboard.aspx Thu, 22 Sep 2011 17:13:47 GMT http://blogs.ugidotnet.org/spboss/archive/2011/09/22/abilitare-la-developer-dashboard.aspx#feedback 2 http://blogs.ugidotnet.org/spboss/comments/commentRss/100382.aspx http://blogs.ugidotnet.org/spboss/services/trackbacks/100382.aspx Attivazione di una Web Feature con Object Model .NET Framework 3.5 SharePoint 2010 http://blogs.ugidotnet.org/spboss/archive/2011/09/22/attivazione-di-una-web-feature-con-object-model.aspx <p>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 <strong>Add</strong> dell'oggetto Features della variabile Web:</p> <pre class="csharpcode"><span class="kwrd">using</span> (SPSite site = <span class="kwrd">new</span> SPSite(<span class="str">"http://sito:8080"</span>)){ <span class="kwrd">using</span> (SPWeb web = site.OpenWeb()){ web.Features.Add(<span class="kwrd">new</span> Guid(<span class="str">"232f367b-33af-4fba-b560-e8a5e56e7ad7"</span>), <span class="kwrd">true</span>); } }</pre><img src="http://blogs.ugidotnet.org/spboss/aggbug/100381.aspx" width="1" height="1" /> Stefano Paterno http://blogs.ugidotnet.org/spboss/archive/2011/09/22/attivazione-di-una-web-feature-con-object-model.aspx Thu, 22 Sep 2011 17:10:43 GMT http://blogs.ugidotnet.org/spboss/archive/2011/09/22/attivazione-di-una-web-feature-con-object-model.aspx#feedback 2 http://blogs.ugidotnet.org/spboss/comments/commentRss/100381.aspx http://blogs.ugidotnet.org/spboss/services/trackbacks/100381.aspx Strumenti per l'Extension Manager di Visual Studio 2010 &ndash; Parte 2 .NET Visual Studio 2010 http://blogs.ugidotnet.org/spboss/archive/2011/09/22/strumenti-per-lextension-manager-di-visual-studio-2010-ndash-parte.aspx <p>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:</p> <p> </p> <p><img alt="" src="http://www.stefanopaterno.com/image.axd?picture=2011%2f9%2fdevcolor.png" />inoltre tenendo premuto il tasto Ctrl verrà creata la toolbar contenente i colori che la vs pagina sta utilizzando, come in figura:</p> <p><img alt="" src="http://www.stefanopaterno.com/image.axd?picture=2011%2f9%2fdevcolor1.png" /></p> <p>Non finisce qui...tenendo premuto Ctrl + click si aprirà la paletta con i colori per impostarne di nuovi:</p> <p><img alt="" src="http://www.stefanopaterno.com/image.axd?picture=2011%2f9%2fdevcolor2.png" /></p><img src="http://blogs.ugidotnet.org/spboss/aggbug/100380.aspx" width="1" height="1" /> Stefano Paterno http://blogs.ugidotnet.org/spboss/archive/2011/09/22/strumenti-per-lextension-manager-di-visual-studio-2010-ndash-parte.aspx Thu, 22 Sep 2011 17:09:37 GMT http://blogs.ugidotnet.org/spboss/archive/2011/09/22/strumenti-per-lextension-manager-di-visual-studio-2010-ndash-parte.aspx#feedback 2 http://blogs.ugidotnet.org/spboss/comments/commentRss/100380.aspx http://blogs.ugidotnet.org/spboss/services/trackbacks/100380.aspx Strumenti per l'Extension Manager di Visual Studio 2010 &ndash; Parte 1 .NET Visual Studio 2010 http://blogs.ugidotnet.org/spboss/archive/2011/09/22/100379.aspx <p>Alcuni simpatici strumenti che potete, gratuitamente, installare su Visual Studio 2010 a supporto dello sviluppo di applicazioni SharePoint 2010 sono:</p> <ul> <li>CSK - Development Tools Edition (Foundation - Server e WTC) </li> <li>Mavention Activate Selected Features </li> <li>Mavention SharePoint Project Item References </li> </ul> <p><strong>CSK - Development Tools Edition</strong></p> <img alt="" src="http://www.stefanopaterno.com/image.axd?picture=2011%2f8%2fCSK.png" /> <p><strong>Mavention</strong></p> <p><img alt="" src="http://www.stefanopaterno.com/image.axd?picture=2011%2f8%2fMavention.png" /></p> <p>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.</p> <p>Volendo è possibile configurarlo per evitare che alla creazione degli oggetti di SharePoint questi vengano associati automaticamente ad una feature.</p><img src="http://blogs.ugidotnet.org/spboss/aggbug/100379.aspx" width="1" height="1" /> Stefano Paterno http://blogs.ugidotnet.org/spboss/archive/2011/09/22/100379.aspx Thu, 22 Sep 2011 17:06:00 GMT http://blogs.ugidotnet.org/spboss/archive/2011/09/22/100379.aspx#feedback 1 http://blogs.ugidotnet.org/spboss/comments/commentRss/100379.aspx http://blogs.ugidotnet.org/spboss/services/trackbacks/100379.aspx