Emanuele Bartolesi

Office 365, SharePoint e ASP.NET

Nasce NTTsight Academy

A metà ottobre inizierà un programma firmato NTTsight a cui ho il piacere di partecipare come ideatore e realizzatore.
Sarà una serie di incontri di due ore sotto forma di sessione, in cui verranno affrontate tematiche riguardanti le ultime tecnologie offerte da Microsoft.
Alla fine di ogni incontro sarà possibile partecipare ad un aperitivo offerto da NTTsight stessa con il contributo di OttimoMassimo.

Il primo incontro (16 ottobre) vedrà come ospite Davide Benvegnù che parlerà di Microsoft Azure Machine Learning e del suo utilizzo durante le attività quotidiane di un'azienda.
Il 12 novembre invece starà a me e vi parlerò dello sviluppo delle App per Office 365 e del loro impiego all’interno delle aziende per migliorarne e ottimizzarne i processi lavorativi, integrati con la intranet.
A dicembre sarà invece la volta di Paola Napolita che ci parlerà di un prodotto recentissimo lanciato da Microsoft: il Microsoft Social Media Listening.

Potete trovare il programma completo all’indirizzo: http://www.nttsight.com/nttsight-academy/ dove potete anche registrarvi ai singoli eventi.
Affrettatevi ad iscrivervi perché i posti sono limitati!

 

logo-nttsight-academy[1]

Materiale WebCast “Tutto su ASP.NET Identity”

Il 15 settembre scorso si è tenuto il webcast targato DotNetToscana su ASP.NET Identity tenuto direttamente da me.
Se non avete avuto la possibilità di guardarlo in diretta, potete trovare il video su YouTube:

Potete trovare le slide su SlideShare all’indirizzo: http://www.slideshare.net/emanuelebartolesi/tutto-su-aspnet-identity e il materiale (comprese le demo) sul nostro sito della community (http://www.dotnettoscana.org/webcast-tutto-su-aspnet-identity.aspx).

That’s all folks!

Convertire una masterpage di SharePoint 2010 in HTML5

Ultimamente sto sviluppando spesso su applicazioni ospitate su SharePoint 2010. Gli sviluppi che però mi vengono richiesti hanno quasi sempre esigenze particolari, come l’inserimento di video, audio, file pdf, direttamente nelle webpart sviluppate.
Alcuni dei tag HTML5 però hanno bisogno che la pagina sia proprio riconosciuta come HTML5.
SharePoint 2010 invece (essendo ormai un prodotto di qualche anno fa) ha le pagine scritte in HTML4.
Effettuare una conversione “semplice” richiede pochi passi, ma permette di utilizzare i nuovi tag HTML5 nelle nuove parti, senza andare a inficiare sulle vecchie parti funzionanti.
Vediamo come fare.

Modificare il DOCTYPE e rimuovere l’attributo xmlns

La prima cosa che dobbiamo fare è modificare il DOCTYPE attuale con quello HTML5 e più precisamente:

<!doctype html>

L’attributo xmlns non è richiesto in HTML5 e quindi possiamo andare a toglierlo, avendo come risultato che il tag <html> abbia questo aspetto:

<html lang="" dir="" runat="server" __expr-val-dir="ltr">

Rimuovere lo slash di chiusura ai tag nell’elemento HEAD

Nell’elemento HEAD della pagina sono presenti alcuni tag con la chiusura all’interno dello stesso elemento. Visto che in HTML5 questo non è più necessario, è possibile rimuovere lo slash di chiusura da tali tag. Attenzione a rimuovere lo slash solo dai tag HTML e non dai tag dei controlli di SharePoint.

Cambiare la compatibilità e il character encoding

Visto che HTML5 non è supportato da IE8, possiamo andare a cambiare il tag meta con attributo http-equiv X-UA-Compatible, inserendo come valore nell’attributo content IE9.

<meta http-equiv="X-UA-Compatible" content="IE=9">

L’altro tag meta che possiamo andare a cambiare, più precisamente a semplificare, è quello del charset. Possiamo rimuovere gli attributi non più necessari ad HTML5, rendendo il tag nel seguente modo:

<meta charset="utf-8">

 

Azioni facoltative (ma non troppo)

Visto che, come abbiamo detto prima, HTML5 non è supportato dai browser inferiori a IE9 e in alcune aziende vive ancora IE8 è necessario essere sicuri che il nostro sito sia visualizzato bene anche in questi browser. Se andiamo però ad utilizzare i nuovi tag semantici di HTML5, come ad esempio section o article, questi non saranno “digeriti” molto bene.
Per ovviare a questo inconveniente è possibile inserire una libreria javascript che in caso di tag non supportati dal browser, li va a sostituire con dei tag “riconosciuti”. Per fare questo è necessario aggiungere nella sezione head, il riferimento al seguente script:

<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>

Come avrete notato ho omesso l’attributo “type” nel tag script, perchè HTML5 di default assume che per i tag script il valore sia sempre “text/javascript”.
Stessa cosa vale anche per i tag “link” dei CSS. Anche in questo caso è possibile omettere l’attributo “type” con il valore “text/css”.
Se avete altri tag di questo tipo all’interno della vostra masterpage, potete tranquillamente andare a modificarli con la nuova regola.

Conclusioni

In questo articolo ho cercato di riassumere la migrazione della masterpage da HTML4 a HTML5. Ovviamente questa è la base di partenza e sono descritti solo gli step base per una migrazione completa, ma questo è più che sufficiente per avere un risultato più che soddisfacente.

Microsoft.Owin si aggiorna alla versione 3.0

Ieri è stato rilasciato un aggiornamento per il progetto Katana portando le librerie Microsoft.Owin alla versione 3.0.
Potete trovare le note di release sulla pagina ufficiale del progetto https://katanaproject.codeplex.com/releases/view/113283.
Si tratta comunque di aggiornamenti legati per lo più alla parte di autenticazione di Google e Twitter (che ha cambiato recentemente questa parte) e della parte di utilizzo dei cookie.
Dalle note si apprende anche che sono state fatte delle modifiche per aumentare le perfomance.

updatekatana

WebCast: Tutto su ASP.NET Identity il 15/09

Il prossimo 15 settembre alle ore 17 si svolgerà un altro webcast targato DotNetToscana.

Questa volta parleremo, e più precisamente parlerò, delle novità introdotte nella versione 2.0 di ASP.NET Identity.
Oltre a vedere le nuove funzionalità, vedremo come creare un nuovo provider custom utilizzando MySQL e SQLite (tempo permettendo) e come utilizzare una tabella di utenti e password già presente nel vostro database.
Gli argomenti da trattare sono molti ed alcuni richiedono un po’ di tempo, ma spero di riuscire a spiegare tutto nel dettaglio e a sciogliere ogni vostro eventuale dubbio su questa funzionalità.

Per i dettagli dell’evento potete fare riferimento alla pagina di facebook https://www.facebook.com/events/687542254663047 dove verranno postati eventuali aggiornamenti. Per quanto riguarda l’iscrizione potete andare sulla pagina di eventbrite https://www.eventbrite.it/e/biglietti-tutto-su-aspnet-identity-12559203917.
Una volta effettuata l’iscrizione all’evento su eventbrite, qualche giorno prima del webcast riceverete le istruzioni per il collegamento.

Link evento: http://www.dotnettoscana.org/webcast-tutto-su-aspnet-identity.aspx

10559823_10152383327873425_5630238788301347813_n

Visual Studio 2013 Update 3 e le SharePoint Apps

Ieri è stato rilasciato l’Update 3 di Visual Studio 2013.
Potete trovare la descrizione completa di ogni singolo update a questo link: http://support.microsoft.com/kb/2933779

Per quanto riguarda lo sviluppo di App per SharePoint 2013 e Office 365, la novità più grande è quella relativa alla rimozione del template delle SharePoint Autohosted Apps.

Riporto qua sotto la nota originale:

Autohosting is no longer an option for SharePoint:
The Autohosted option is removed from the SharePoint application creation experience, because the Office 365 Autohosted Apps Preview program ended on June 30. New autohosted applications for SharePoint are no longer accepted by the SharePoint store. Existing autohosted apps are not affected, and apps that are currently running in the service will not be shut down.

Quindi se avete già sullo store di Office delle applicazioni sviluppate in questa modalità, non ci sono problemi, ma in futuro è preferibile utilizzare le Provider Hosted Apps.

Ho affrontato questo argomento durante un webcast qualche mese fa.

Impostare un colore di sfondo di una jQuery UI Dialog

jQueryUI mette a disposizione un un buon numero di widget da poter usare nelle nostre applicazioni web.
Uno di questi si chiama “Dialog” ed è un div che viene renderizzato come se fosse una finestra popup all’interno della nostra pagina HTML.
Può essere impostato anche in modalità “modal” risultando sopra ad ogni altro elemento e dovrà essere chiuso prima di poter utilizzare gli altri componenti della pagina.

Quando il controllo è aperto, viene inserito un colore di sfondo più scuro per far capire che la finestra è modale.
Questo colore ovviamente può essere variato, seguendo le linee grafiche del nostro sito.
Per fare questo è possibile cambiare direttamente il css legato alla controllo, oppure fare la stessa cosa, ma utilizzando gli eventi del widget.
Personalmente preferisco usare il secondo metodo in quanto funziona su tutti i browser, mentre nel primo caso può dare qualche problema su versioni vecchie di IE.

Primo metodo

.ui-widget-overlay
{
  opacity: .30 !important; 
  filter: Alpha(Opacity=30) !important;

  background-color: rgb(0, 0, 0) !important;
}

Secondo metodo

open : function(event, ui){
    $("body").css({
        overflow: 'hidden'
    });
    $(".ui-widget-overlay").css({
        background:"rgb(0, 0, 0)",
        opacity: ".30 !important",
        filter: "Alpha(Opacity=30)",
    });
},
beforeClose: function(event, ui) {
    $("body").css({ overflow: 'inherit' })
}

I plugin jQuery che non possono mancare nelle vostre applicazioni ASP.NET

Ormai le applicazioni web richiedono la stessa capacità di interazione delle applicazione desktop a cui gli utenti sono stati abituati per anni.
Con HTML5, CSS3 e jQuery questo non è più un risultato così difficile da ottenere.

Di seguito riporto alcuni dei plugin che non possono mancare nelle vostre applicazioni ASP.NET per migliorare l’usabilità e rendere i contenuti di facile fruizione da parte degli utenti.

  • noty: permette di inserire dei messaggi simili agli alert di outlook o delle toast notification.
  • NProgress.js: per inserire una barra di caricamento in alto alla pagina per dare un feedback all’utente sullo stato dei download o delle chiamate asincrone della pagina
  • jQuery.Inputmask: un plugin che permette di trasformare una casella di testo in una input mask con vari formati: date, numeri e la possibilità di inserire direttamente regex personalizzate
  • jquery-watermark: permette di inserire un watermark nelle caselle di testo
  • jquery news ticker: un news ticker sullo stile dei notiziari
  • jTable: facile e veloce da imparare per creare tabelle con filtri, ordinamenti e finestre di modifica dei dati. E’ stata realizzata da uno sviluppatore ASP.NET e quindi è facilmente integrabile. Ci sono direttamente gli esempi con ASP.NET MVC
  • jqGrid: un’altro plugin per realizzare tabelle. Molto ricco di funzionalità, ma personalmente preferisco jTable
  • jQuery Format Currency: questo plugin permette di formattare una casella di testo con la valuta di 211 paesi. Molto semplice da usare e gli esempi sul sito sono esaustivi
  • dropzonejs: permette l’upload di file di qualsiasi tipo anche con il drag&drop direttamente sulla pagina. In caso di immagini fa vedere anche l’anteprima.
  • jQueryUI Sortable: nel caso aveste bisogno di una lista ordinabile questo fa al caso vostro
  • jQueryUI Datepicker: un datepicker facile da configurare, ma con tante personalizzazioni
  • anoSlide: uno slider di immagini molto bello e semplice da personalizzare
  • Flot: tantissimi tipi di grafici molto belli graficamente e interattivi. Possibilità di aggiornare i grafici anche tramite chiamate AJAX.
  • jQuery Loader Fullscreen: un loader a tutto schermo semplice da usare. E’ un mio progetto su GitHub. :)

La lista potrebbe essere molto più lunga, ma questa è una buona base di partenza per rendere le vostre applicazioni più accattivanti e user-friendly.

Rendere Outlook 2013 più social che mai

In Outlook 2013 è stata introdotta una barra nel riquadro di lettura che visualizza gli aggiornamenti e i messaggi sotto forma di discussione dei contatti presenti nella mail.
Questa funzionalità può essere estesa anche ad account esterni per essere sempre aggiornati sui propri contatti, senza ogni volta aprire tutti i vari social.
Inoltre, un comportamento che trovo molto utile, se l’utente è esterno alla propria rete, viene aggiunta una foto prelevata direttamente dal social con cui è registrata quella mail.

Per attivare questa funzionalità, selezionare dal ribbon di Outlook:

View –> People Pane –> Account Settings

Outlook1

Nella nuova schermata, selezionare i social che vi interessano e premere su Connect.

Una volta effettuati i login e concesso l’accesso alle vostre informazioni del social, cliccare su Finish.

Outlook2
A questo punto, nella barra di lettura della mail dove ci sono i contatti, appariranno foto prese dai vari social e gli aggiornamenti.

SharePoint 2013 – Rimuovere il campo Title con il Client Object Model

Quando facciamo il provisiong su SharePoint 2013 o Office 365 dalle nostre App a volte è necessario dover eliminare dei campi dalle liste che vengono inseriti di default.
Per fare questo è sufficiente eseguire una DeleteObject sul campo che vogliamo eliminare:

ClientContext clientContext = new ClientContext(siteUrl);
Web web = clientContext.Web;
List list = web.Lists.GetByTitle("MyList");
Field field = list.Fields.GetByTitle("Surname");
field.DeleteObject();
clientContext.ExecuteQuery();


Discorso diverso invece è per il campo Title che ha bisogno di qualche impostazione aggiuntiva per essere rimosso sia dalla lista, sia dalla vista o dalle viste in cui appare:

ClientContext clientContext = new ClientContext(siteUrl);
Web web = clientContext.Web;
List list = web.Lists.GetByTitle("MyList");
Field field = list.Fields.GetByTitle("Title");

field .Hidden = true;
field .Required = false;
field .SetShowInDisplayForm(false);
field .SetShowInEditForm(false);
field .SetShowInNewForm(false);

View view = list.Views.GetByTitle("All Items");
ViewFieldCollection viewFields = view.ViewFields;
viewFields.Remove("LinkTitle");
view.Update();

clientContext.ExecuteQuery();

MVP per la prima volta!

Lo scorso 1° luglio sono stato nominato Microsoft MVP su ASP.NET.

Ho approfittato di questi giorni prima di scrivere per fare mente locale sull’ultimo anno di vita lavorativa e personale.
E’ stato un anno molto intenso, soprattutto dal punto di vista professionale.
Tanti progetti da seguire, tanti progetti nuovi, eventi in giro per l’Italia e un trasferimento per fare ritorno a Milano.
Potrei stare ore a ringraziare tutti quanti, ma le persone che voglio ringraziare prima di tutte, sono Marco Minerva e Marco Dal Pino che mi hanno aiutato in questo percorso, a migliorarmi e a spronarmi nei momenti in cui la fiducia in me stesso scendeva sotto i livelli di sicurezza. :)
Il raggiungimento di questo obiettivo comunque non è un punto di arrivo, ma un checkpoint intermedio per cercare ancora di migliorare e di rimanere a far parte di questo fantastico gruppo fatto di persone prima che da professionisti.

Grazie anche a tutto lo staff di DotNetToscana, di cui faccio parte, per il supporto.microsoft-mvp

Script PowerShell per scaricare tutti i video di DotnetConf14

Ho preparato uno script PowerShell per scaricare tutti i video della recentissima DotNetConf14.

Lo potete trovare su Gist a questo link: https://gist.github.com/kasuken/891f4102e807b2dbb78c

mkdir "~\Desktop\DotNetConf14"
cd "~\Desktop\DotNetConf14"
[Environment]::CurrentDirectory=(Get-Location -PSProvider FileSystem).ProviderPath
$a = ([xml](new-object net.webclient).downloadstring("http://s.ch9.ms/Events/dotnetConf/2014/RSS/mp4high"))
$a.rss.channel.item | foreach{  
      $url = New-Object System.Uri($_.enclosure.url)
    
    $file = "- " + $_.creator + " - " + $_.title.Replace(":", "-").Replace("?", "").Replace("/", "-").Replace("<", "").Replace("|", "").Replace('"',"").Replace("*","")
    $file = $file.substring(0, [System.Math]::Min(120, $file.Length))
    $file = $file.trim()
    
    $OutFile = New-Item -type file "$file.txt" -Force  
    $Content = ""
    $Content = $_.title.trim() + "`r`n" + $_.summary.trim()
    add-content $OutFile $Content
    
    "Downloading: " + $file + ".mp4"
    if (!(test-path $file))
    {
      $wc = (New-Object System.Net.WebClient)  
      $wc.DownloadFile($url, $file + ".mp4")
    }
}

Bootstrap 3 in 15 minuti

Bootstrap è un framework HTML, CSS e Javascript. Il suo scopo è quello di aiutare a disegnare layout per siti o applicazioni web in poco tempo e adatti a qualsiasi tipo di browser e risoluzione.

Ormai arrivato alla versione 3, si può considerare quasi uno standard per lo sviluppo di layout responsive.

In questo breve tutorial andremo a vedere le basi di questo framework da cui partire per realizzare layout più complessi utilizzando le classi base di Boostrap.

La prima pagina

Per prima cosa dobbiamo creare una pagina HTML5 con l’editor HTML che preferite (io uso questo) e inserire i riferimenti ai CSS e al Javascript di Bootstrap.
Se non volete avere una copia dei file sul vostro server, potete utilizzare un server CDN (www.bootstrapcdn.com) che mette a disposizione i file necessari.

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>

    <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
    <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
</body>
</html>

E’ disponibile sia con protocollo http che https.
Di norma viene aggiunto anche jQuery per utlizzare funzioni più avanzate di Boostrap che andremo a vedere nei prossimi post.

Jumbotron

La pagina che abbiamo creato adesso è ancora bianca perchè non abbiamo disegnato nessun elmento HTML. Il primo che andremo a inserire si è un div a cui andremo ad applicare una delle classi css di Boostrap denominata “jumbotron”.
Questa classe serve a creare una sezione di intestazione della pagina in cui possiamo inserire titoli, sottotitoli, pulsanti di navigazione.

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>
    <div class="container">
        <div class="jumbotron">
                <h1>First Page in Bootstrap</h1>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
    <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
</body>
</html>

In questo caso siamo andati a inserire il titolo “First Page in Bootstrap” all’interno di un tag <h1> per impostare un titolo alla pagina.
All’interno del jumbotron però possiamo inserire qualsiasi tipo di altro tag HTML, come ad esempio:

<p>Are you happy developer?</p>
<p><a class="btn btn-primary btn-lg" href="http://www.emanuelebartolesi.com" target="_blank">Learn more</a></p>
 
Righe e colonne

In Bootstrap ogni sezione di una pagina è rappresentata da un div con applicata la classe “row”. All’interno di ogni sezione “row” è possibile inserire più sezioni orizzontali semplicemente inserendo uno o più div al suo interno.
Ai div interni possiamo applicare le classi “col-lg”, “col-md”, “col-sd” e “col-xs”.
Queste classi vogliono dire che la colonna appena creata si adatterà, rispettivamente, a uno schermo largo, medio, piccolo e molto piccolo. In questo modo è possibile impostare un layout per ogni tipo di risoluzione. Se invece vogliamo utilizzare un layout che si adatti a qualsiasi tipo di schermo, possiamo utilizzare la classe “col-md”.

Bootstrap utilizza un sistema a 12 colonne (12 Grid System). Questo vuol dire che se voglio creare due colonne larghe uguali, devo creare due div e applicare a entrambe la classe css “col-md-6”. Se ne volessi invece creare 4, dovrei fare 4 div con la classe “col-md-3” applicata.

<div class="container">
    <div class="row">
        <div class="col-md-4">
        
        </div>
        <div class="col-md-4">

        </div>
        <div class="col-md-4">

        </div>
    </div>
</div>

Se aggiungiamo lo snippet  di codice sopra, avremmo 3 div, larghi 4 colonne l’uno perfettamente responsive.
Il codice completo con il contenuto di prova:

<div class="container">
    <div class="row">
        <div class="col-md-4">
            <h2>Heading 1</h2>
            <p align="justify">Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
            <p><a class="btn btn-default btn-primary" href="#">View details &raquo;</a></p>
        </div>
        <div class="col-md-4">
            <h2>Heading 2</h2>
            <p align="justify">Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
            <p><a class="btn btn-default btn-primary" href="#">View details &raquo;</a></p>
        </div>
        <div class="col-md-4">
            <h2>Heading 3</h2>
            <p align="justify">Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
            <p><a class="btn btn-default btn-primary" href="#">View details &raquo;</a></p>
        </div>
    </div>
</div>
 
Menu di navigazione

Una delle parti più importanti per ogni sito è la navigazione.
Anche in questo caso Bootstrap ha già un comportamento e della classi predefinite che possono semplificarne lo sviluppo.

Anche la barra di navigazione è un div, con la classe “navbar” applicata.
All’interno del div principale, ci sono altri div che andranno a formare il menu vero e proprio.
Le cose fondamentali da sapere sono che se inseriamo un button e gli applichiamo la classe “navbar-toggle”, questo sarà nascosto fino a che il nostro browser sarà a risoluzioni abbastanza elevate, ma durante la navigazione di un dispositivo mobile, verrà visualizzato il contenuto di questo tag. Di solito viene visualizzato come un pulsante con delle righe orizzontali.
Un altro elemento fondamentale, sempre da inserire all’interno del div con classe “navbar-header” è un tag link con classe “navbar-brand”.
Questo sarà visualizzato di default a sinistra del menu con solitamente il titolo del sito.
L’ultimo div che forma la navigazione, è un div con classe css “navbar-collapse”.
In questo div, attraverso un elenco ul->li, è possibile inserire i link del sito, anche annidandoli come un normale elenco puntato. Gli elementi di secondo livello, verrano visualizzati di default in un menu a discesa quando il mouse si sposterà sull’elemento principale.

Il codice per realizzare il menu appena descritto è il seguente:

<div class="navbar navbar-inverse navbar-default navbar-fixed-top" role="navigation">
  <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">Bootstrap first page</a>
    </div>
    <div class="navbar-collapse collapse">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Home</a></li>
        <li><a href="#about">Second link</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
          <ul class="dropdown-menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
          </ul>
        </li>
      </ul>
    </div>
  </div>
</div>

A questo link, potete trovare l’esempio completo della pagina creata in questo tutorial.

image

SharePoint 2013: recuperare il numero di versione di un item con il Client Object Model

Spesso è necessario visualizzare il numero di versione di un Item di una lista presente in SharePoint nelle nostre applicazioni che utlizzano il Client Object Model.
Per recuperare tale valore, bisogna prima recuperare il riferimento alla lista, poi tutti gli item e infine recuperare il valore attraverso il nome del campo “_UIVersionString”.
Diamo un’occhiata al codice, supponendo di avere una lista denominata “Products” e il versioning abilitato sulla lista.

ClientContext cc = new ClientContext("Your Site Url");
Web web = cc.Web;

List list = web.Lists.GetByTitle("Products");

CamlQuery caml=new CamlQuery();
ListItemCollection items = list.GetItems(caml);

cc.Load(list);
cc.Load(items);
cc.ExecuteQuery();

foreach (Microsoft.SharePoint.Client.ListItem item in items)
{
    var version = item.FieldValues["_UIVersionString"].ToString();
}

Nascondere l’icona e il titolo di un’app per SharePoint o Office 365

Quando realizziamo un'app per SharePoint 2013 o Office 365 in modalità Sharepoint-Hosted non abbiamo la possibilità di cambiare completamente l'impostazione delle pagine che compongono la nostra applicazione e di default viene inserito in ogni pagina il titolo della nostra app e il logo.

A volte questa cosa può non rispettare gli standard grafici che ci siamo prefissati per la nostra App.

Per eliminare la barra del titolo è sufficiente inserire nei css dell'App o nella singola pagina in cui vogliamo eliminare l'elemento il seguente snippet di CSS.

#s4-titlerow{
    display:none !important;
}

Creare un campo di tipo rich text in SharePoint 2013

Questo post nasce dall’esigenza di colmare un piccolo gap della documentazione presente su MSDN in cui non viene spiegato in maniera esaustiva la modalità di creazione di un campo “Note” con la possibilità di avere il completo supporto a HTML e una casella di testo in stile WYSIWYG in fase di inserimento e modifica del record.
L’XML corretto per creare un campo di questo tipo è il seguente:

<Field
    Name="Body"
    DisplayName="Body"
    Type="Note"
    RichText="TRUE"
    RichTextMode="FullHtml"    
    Sealed="FALSE"
    ReadOnly="FALSE"
    Hidden="FALSE"
    DisplaceOnUpgrade="TRUE" />

I due tag fondamentali sono RichText="TRUE e RichTextMode="FullHtml".
E’ da notare che il Type del campo deve essere “Note” anzichè “Text”.

Amministrare SharePoint 2013 da PowerShell – Parte 2

Nell’articolo precedente abbiamo visto come creare da script una web application.
Il passo successivo è quello di creare una site collection sotto la stessa web application.

Anche in questo caso, se non lanciamo lo script dalla console PowerShell di SharePoint, è necessario aggiungere lo Snapin necessario per includere gli oggetti di SharePoint.
Il parametro $SiteUrl deve essere impostato con l’url del sito della web application di riferimento.
E’ anche possibile scegliere se avere la user experience di SP2010 o SP2013. Altro parametro fondamentale è il template della Site Collection.
All’indirizzo http://www.funwithsharepoint.com/sharepoint-2013-site-templates-codes-for-powershell/ è possibile trovare la lista completa di tutti i template che si possono usare.

Remove-PSSnapin Microsoft.SharePoint.Powershell -ErrorAction SilentlyContinue
Add-PSSnapin Microsoft.SharePoint.Powershell

$SiteUrl="site url"

#14 for SharePoint Server 2010 experience sites or 15 for SharePoint Server 2013 
$CompatibilityLevel=15

<#
#Specifies the language ID for the new site collection
#This must be a valid language identifier (LCID).
#http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splanguage.lcid.aspx
#1033 English
#>
$Language=1033

#Specifies the title of the new site collection
$Name="Nome Sito"

#Site description
$Description=""    

$OwnerAlias = "domain\nome utente"
$OwnerEmail = "email@domain.com"

#Template Disponibili:
#http://www.funwithsharepoint.com/sharepoint-2013-site-templates-codes-for-powershell/
$Template="BLANKINTERNETCONTAINER#0"

New-SPSite $SiteUrl -Template $Template -OwnerAlias $OwnerAlias -CompatibilityLevel $CompatibilityLevel -Description $Description -Language $Language -Name $Name -OwnerEmail $OwnerEmail

Amministrare SharePoint 2013 da PowerShell – Parte 1

SharePoint 2010 e SharePoint 2013 possono essere amministrati quasi interamente da PowerShell. Questo fa un pò il bello e il cattivo tempo degli sviluppatori e dei sistemisti che devono impostare alcune feature e comportamenti degli ambienti di sviluppo e produzione.
Una delle comodità ad esempio è che con gli script, si può creare molto rapidamente una web application e replicarla con le stesse impostazioni su tutti gli ambienti che servono (sviluppo, test, collaudo e produzione ad esempio).

In questo primo script andremo a vedere come creare una web application nuova da PowerShell. Per prima cosa bisogna abilitare l’esecuzione degli script sul server seguendo l’altro mio articolo di qualche giorno fa.

Remove-PSSnapin Microsoft.SharePoint.Powershell -ErrorAction SilentlyContinue
Add-PSSnapin Microsoft.SharePoint.Powershell

$name="Web Application Name"
$appPool="App Pool"
$poolAccount="pool account"
$dbName="Mediobanca DB"
$waURL="http://site url"

try 
{
    $ap = New-SPAuthenticationProvider
    New-SPWebApplication -Name $name -URL  $waURL -ApplicationPool  $appPool -ApplicationPoolAccount (Get-SPManagedAccount $poolAccount ) -AuthenticationProvider $ap -DatabaseName $dbName
}
catch
{
    write-host "Error" $_.exception -foregroundcolor Red
}

Se lo script non viene lanciato dalla console PowerShell di SharePoint è necessario per prima cosa aggiungere lo Snapin Microsoft.SharePoint.Powershell, in modo da avere gli oggetti di SharePoint disponibili.
Per comodità ho inserito nello script delle variabili che possono e devono essere cambiate in base alle esigenze del momento, come ad esempio il nome dell’application pool, il nome del database di riferimento e l’account con cui verrà eseguito l’application pool nel formato “dominio\nome utente”.

Determinare se un Application Pool è di SharePoint

Con questo piccolo script è possibile determinare se un Application Pool appartiene a un sito di SharePoint o meno.

Add-PsSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
Import-Module WebAdministration -ErrorAction SilentlyContinue

$AppPoolDisplayName = "App Pool Display Name"

if(Get-SPServiceApplicationPool $AppPoolDisplayName -ErrorAction SilentlyContinue)
{
    Write-Host "The $AppPoolDisplayName is a SharePoint Application Pool"
}
else
{
    if((Test-Path IIS:\AppPools\$AppPoolDisplayName).tostring() -eq "True")
    {
       Write-Host "The $AppPoolDisplayName exists but it isn't a SharePoint Application Pool"
    }
    else
    {
    Write-Host "The $AppPoolDisplayName not exists"
    }
}

Post “Fiera del Radioamatore 2014”

Ieri si è conclusa l'avventura di DotNetToscana alla Fiera del Radioamatore di Pordenone.
Un evento molto bello e ben organizzato. Il nostro padiglione era quello dedicato ad "AppDays", dove hanno preso parte Community e User Group da tutta Italia e di tecnologie diverse: si potevano trovare stand su Linux, Apple, Stampanti 3D, embedded, droni costruiti in casa.

Per noi l’esperienza è stata ancora più significativa perché era la prima volta che invitavano qualcuno dello stack tecnologico Microsoft, e dunque si è trattato di una sfida nella sfida. Direi comunque che il riscontro ottenuto ha persino superato le aspettative.

Noi di DotNetToscana abbiamo erogato sessioni su Windows Phone 8 e Windows 8 tra cui: utilizzo delle mappe, in-app purchase, servizi per le app (Web API), interazione con device esterni e l'immancabile volo del drone.
Nel complesso, abbiamo riscontrato un buon numero di partecipanti, anche tenendo conto che si trattava di una vera propria fiera e non di un evento classico ricco di sessioni e di track.

Anche questa volta, la sessione con il maggior numero di partecipanti e il più grande interesse, anche da parte di persone che passavano di lì per caso, è stata quella del drone. E' sempre affascinante veder volare un drone comandato da un cellulare con la schermata dell'app proiettata sul maxitelo dell'arena principale della Fiera.

Come sempre grazie ai miei compagni di viaggio, Marco Minerva e Marco Dal Pino: risate, divertimento e cene.

Un ringraziamento particolare a Marco Parenzan che ci ha invitato per questa fantastica esperienza che come sempre ha l'illusione di essere durata troppo poco quando si torna a casa.

WP_20140426_10_54_11_Pro

Script PowerShell per scaricare tutti i video e le slides di Build 2014

Qualche giorno fa ho pubblicato su GitHub uno script PowerShell per scaricare tutti i video e le slides di Build 2014.
Usarlo è molto facile perchè basta scaricarlo e lanciarlo.

Se eventualmente volete cambiare il path dove vengono scaricati i files, aprite lo script e modificate il path C:\Build2014, con quello che preferite.

La pagina del progetto GitHub è questa: downloadbuild14videos
Se volete scaricare direttamente lo script potete usarlo invece usando quest’altro link: downloadbuild14videos as a zip file

image_thumb

[Environment]::CurrentDirectory=(Get-Location -PSProvider FileSystem).ProviderPath 
$rss = (new-object net.webclient)

# Build 2014 Videos and Slides
$video = ([xml]$rss.downloadstring("http://channel9.msdn.com/Events/Build/2014/RSS/mp4high")) 
$slides = ([xml]$rss.downloadstring("http://channel9.msdn.com/Events/Build/2014/RSS/slides")) 

#Preferably enter something not too long to not have filename problems! cut and paste them afterwards
$downloadpath = "C:\Build14"

if (-not (Test-Path $downloadpath)) { 
    Write-Host "Folder $downloadpath doesn't exist. Creating it..."  
    New-Item $downloadpath -type directory 
}

set-location $downloadpath

#download all videos
$video.rss.channel.item | foreach{   
        $code = $_.comments.split("/") | select -last 1       
        
        # Grab the URL for the MP4 file
        $url = New-Object System.Uri($_.enclosure.url)  
        
        # Create the local file name for the MP4 download
        $file = $code + "-" + $_.creator + "-" + $_.title.Replace(":", "-").Replace("?", "").Replace("/", "-").Replace("<", "").Replace("|", "").Replace('"',"").Replace("*","")
        $file = $file.substring(0, [System.Math]::Min(120, $file.Length))
        $file = $file.trim()
        $file = $file + ".mp4"  
        
        if ($code -ne "")
        {
             $folder = $code + " - " + $_.title.Replace(":", "-").Replace("?", "").Replace("/", "-").Replace("<", "").Replace("|", "").Replace('"',"").Replace("*","")
             $folder = $folder.substring(0, [System.Math]::Min(100, $folder.Length))
             $folder = $folder.trim()
        }
        
        if (-not (Test-Path $folder)) { 
            New-Item $folder -type directory 
        }
        
        # Make sure the MP4 file doesn't already exist
        if (!(test-path "$folder\$file"))     
        {     
            # Echo out the  file that's being downloaded
            $file
            $wc = (New-Object System.Net.WebClient)  

            # Download the MP4 file
            $wc.DownloadFile($url, "$downloadpath\$file")
            # When download is finished, move file
            mv $file $folder
        }
        else
        {
            Write-Host "You have already the $file video. The download is skipped."
        }
    }

#Download the slides    
$slides.rss.channel.item | foreach{   
        $code = $_.comments.split("/") | select -last 1       
    
        # Get the URL for the PPTX file
        $urlpptx = New-Object System.Uri($_.enclosure.url)  
        $filepptx = $code + "-" + $_.creator + " - " + $_.title.Replace(":", "-").Replace("?", "").Replace("/", "-").Replace("<", "").Replace("|", "").Replace('"',"").Replace("*","")
        $filepptx = $filepptx.substring(0, [System.Math]::Min(120, $filepptx.Length))
        $filepptx = $filepptx.trim()
        $filepptx = $filepptx + ".pptx"

        if ($code -ne "")
        {
             $folder = $code + " - " + $_.title.Replace(":", "-").Replace("?", "").Replace("/", "-").Replace("<", "").Replace("|", "").Replace('"',"").Replace("*","")
             $folder = $folder.substring(0, [System.Math]::Min(100, $folder.Length))
             $folder = $folder.trim()
        }
    
        if (-not (Test-Path $folder)) {   
            New-Item $folder -type directory 
        }
    
        #Get text description from session
        $OutFile = New-Item -type file "$($downloadpath)\$($Folder)\$($Code.trim()).txt" -Force  
        $Category = "" ; $Content = ""
        $_.category | foreach {$Category += $_ + ","}
        $Content = $_.title.trim() + "`r`n" + $_.creator + "`r`n" + $_.summary.trim() + "`r`n" + "`r`n" + $Category.Substring(0,$Category.Length -1)
        add-content $OutFile $Content

        # If PowerPoint file doesn't already exist
        if (!(test-path "$downloadpath\$folder\$filepptx"))     
        {     
            # Echo out the  file that's being downloaded
            $filepptx
            $wc = (New-Object System.Net.WebClient)  

            # Download the MP4 file
            $wc.DownloadFile($urlpptx, "$downloadpath\$filepptx")
            # When download is finished, move file
            mv $filepptx $folder 
        }
        else
        {
            Write-Host "You have already the $filepptx presentation. The download is skipped."
        }
    }

Diventare freelance: i consigli, i vantaggi e gli svantaggi

Ultimamente sto parlando spesso con persone che per scelta di vita o scelta obbligata sono diventate freelance. Nel primo caso c'è poco da dire. Ognuno fa quello che crede e se l'obiettivo di lavorare in proprio era importante per loro hanno fatto bene a farlo. Nel secondo caso invece, basta guardare i dati dell'agenzia delle entrate, per capire che negli ultimi anni c'è stato un boom di apertura di partite iva. Questo spesso è dovuto al fatto che molte aziende hanno chiuso i battenti per mancanza di lavoro, ma sopratutto per mancanza di fondi. Alcuni datori di lavoro hanno deciso infatti di licenziare i propri dipendenti e farli lavorare da "esterni". In questo modo le aziende si sono tolte "il peso" di avere ogni mese degli stipendi fissi da pagare.

La vita da freelance comunque non è per niente facile e da prendere sottogamba. Il freelance si deve dimenticare per prima cosa uno stipendio fisso a una data fissa del mese e può fare affidamento solo sulla propria forza d'animo.

I vantaggi

  • Fare il lavoro che piace e che spesso è/era anche un hobby
  • Totale indipendenza da altri
  • Lavorare per più clienti e progetti (non ci si annoia mai)
  • Maggior guadagno
  • Motivazione continua nel lavorare perché il freelance è l'artefice del proprio successo

Gli svantaggi

  • Orari di lavoro non più fissi
  • Scadenze fiscali
  • Non ci sono più ferie, malattia o permessi. Quando non si lavora, non si guadagna e si ritardano le consegne
  • Si lavora 6-7 giorni alla settimana. Non più 5
  • Difficoltà a distrarsi dal lavoro perchè diventa parte integrante della vita

La mia esperienza

La scelta di diventare freelance per me è arrivata un pò per caso e un pò perché sono stato forzato da una serie di situazioni. La cosa certa è che rifarei la scelta come ho fatto quasi tre anni fa e forse la farei addirittura prima. Ho cercato di elencare i vantaggi e gli svantaggi in maniera oggettiva, ma nonostante non sia tutto rosa e fiori è sicuramente una bella esperienza di vita che fa crescere anche molto, sia professionalmente che umanamente.

L'unica cosa che mi posso permettere di dirvi, se decidete di fare il grande passo, è quella di scegliere un argomento o un'attività e cercare di diventare specializzato in quella. I tuttologi al giorno d'oggi nel mondo dell'informatica non possono esistere e se si è bravi a fare una cosa, è più facile trovare nuovi clienti e nuovi progetti.