lunedì 18 dicembre 2017

Open in file explorer

Da vecchio utilizzatore di Sharepoint e per inveterata abitudine uso sempre la scorciatoia "open in file explorer". Purtroppo ormai sembra retaggio solo di IE, quindi a promemoria futura: in file explorer \\sitosharepoint\DavWWWRoot e http://sitosharepoint/_catalogs/masterpage

martedì 21 novembre 2017

Piccolo vademecum (un po' criptico :-) ) per SP Framework

windows powershell come amministratore
cd su directory soluzioni
cd directory della soluzione
code . (chi sa il perchè di questo comando? :-) )
gulp serve è per testarla localmente
npm shrinkwrap opzionale è per bloccare le dipendenze del progetto
gulp bundle --ship build (package-solution.json per la versione)
gulp package-solution --ship per creare il package per il deploy su SPO

giovedì 2 novembre 2017

Error occurred in deployment step 'Recycle IIS Application Pool': Provider load failure

Non è un errore molto diffuso, ma prima di rompervi la testa come ho fatto io, si risolve semplicemente installando gli IIS 6 Compatibility components come indicato qui.




venerdì 27 ottobre 2017

Per chi inizia con gli Sharepoint add-ins

Un po' di codice già pronto da utilizzare in tutti gli addins Sharepoint-hosted che debbano accedere all'host web.

// Function to retrieve a query string value.
// For production purposes you may want to use
//  a library to handle the query string.
function getQueryStringParameter(paramToRetrieve) {
    var params =
        document.URL.split("?")[1].split("&");
    var strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == paramToRetrieve)
            return singleParam[1];
    }
}

var clientContext = SP.ClientContext.get_current();
var hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
var appweburl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));


$.getScript("../_layouts/15/SP.RequestExecutor.js", initializePart);

function initializePart() {
    var factory = new SP.ProxyWebRequestExecutorFactory(appweburl);
    clientContext.set_webRequestExecutorFactory(factory);
    var appContextSite = new SP.AppContextSite(clientContext, hostweburl);
    workWeb = appContextSite.get_web();
    clientContext.load(workWeb);
    clientContext.executeQueryAsync(ongetWebSuccess, ongetWebFail);
}



lunedì 23 ottobre 2017

Powershell Script per rimuovere la version da un campo

Dopo essermi scontrato di nuovo con questo problema (che è micidiale nel caso dei Taxonomy o Managed Metadata Fields), ecco uno script PowerShell per rimuovere la version da un campo anche se è già contenuto in un content type. PowerShell rules!! :-)



$name = "qui ci va l'internal name del campo"
$url = "qui ci va l'url della sitecollection"
Write-Host ("Remove Version flag from '{0}' in '{1}'" -f $name, $url)

$web = Get-SPWeb $url
$web = $web.site.RootWeb
$field = $web.Fields.GetFieldByInternalName($name)
if (!$field) {
    Write-Host "> Can't find field!" -ForegroundColor:Red
    break
}
[xml]$xml = $field.SchemaXml
$contenttypenames = $web.ContentTypes | ? { $_.FieldLinks | ? { $_.Id -eq $field.ID } } | ? { $_.Parent.Fields.ContainsFieldWithStaticName($field.InternalName) -eq $false } | % { Write-Output $_.Name }

$contenttypenames | % {
    $contenttypename = $_
    write-host ("> Remove field link from {0}..." -f $contenttypename) -ForegroundColor:Green
    $ct = $web.ContentTypes[$contenttypename]
    $ct.FieldLinks.Delete($name)
    $ct.UpdateIncludingSealedAndReadOnly($true)
}

$field = $web.Fields.GetFieldByInternalName($name)
if ($field) {
    Write-Host "> Deleting existing field..." -ForegroundColor:Green
    $web.fields.Delete($name)
}

Write-Host "> Adding field (version removed)..." -ForegroundColor:Green
$xml.Field.RemoveAttribute("Version")
$web.Fields.AddFieldAsXml($xml.OuterXml) | Out-Null

$contenttypenames | % {
    $contenttypename = $_
    Write-Host ("> Adding field link to {0}..." -f $contenttypename) -ForegroundColor:Green
    $field = $web.Fields.GetFieldByInternalName($name)
    $fieldlink = New-Object Microsoft.SharePoint.SPFieldLink($field)
    $ct.FieldLinks.Add($fieldlink)
    $ct.Update($true)
}

martedì 10 ottobre 2017

Search Engine Optimization (SEO) - Minimizzare js e css

Vi segnalo velocemente un articolo nel caso dobbiate ottimizzare un sito per i motori di ricerca e vogliate minimizzare i files js e Css per migliorare la Page speed. L'articolo propone di utilizzare Microsoft Ajax Minifier disponibile a questo link e tratta il caso di un app Sharepoint, ma le indicazioni in esso contenute vanno bene per un qualunque progetto Sharepoint. Automating JavaScript and CSS Minification In SharePoint Apps


martedì 8 agosto 2017

Esportare una lista in XML

Il trucco è conosciuto e consiste nell'utilizzare questo formato di url

http://<site url>/_vti_bin/owssvr.dll?Cmd=Display&List=<listid>&View=<view guid>&Query=*&XMLDATA=TRUE

Una volta ottenuto il file xml con un po' di pazienza e di codice potete importare le liste cosí serializzate in un'altra farm (previa creazione degli eventuali custom content types creati)

lunedì 19 giugno 2017

Attenzione!! Rimuovete l'attributo 'Version' se esportate e importate le Site Columns con Powershell

Come dice il titolo, eliminate l'attributo 'Version' da ogni tag Field che lo contiene nel file XML generato se esportate e importate le Site Columns con Powershell, altrimenti non potrete modificare la Site Column in nessun modo.

domenica 4 giugno 2017

Aggiornare un Taxonomy Field utilizzando l'object model

(Aggiornamento: accertatevi di avere gli stessi language packs se lavorate su farm diverse per via dei campi aggiunti alla TaxonomyHiddenList)


Per aggiornare un campo Taxonomy va utilizzato il metodo statico SetFieldValue della classe TaxonomyField. Nel caso però in cui il campo appartiene ad un content type pubblicato attraverso il Content Type Hub o sia creato in Visual Studio e la definizione non sia del tutto corretta si avrà il seguente criptico errore "The SPListItem being updated was not retrieved with all taxonomy fields". Il metodo sicuro per l'update è il seguente, dove aggiorniamo un taxonomy field multivalued, per i single valued si utilizza TaxonomyFieldValue e non TaxonomyFieldValueCollection, e il tutto si basa sul fatto che il TaxonomyField ha un campo Note nascosto associato:


  // create new TaxonomySession based on the current Site
TaxonomySession taxonomySession = new TaxonomySession(oSite);
TermStore termStore = taxonomySession.DefaultKeywordsTermStore;

// connect to the Term Store Group
var group = termStore.Groups["Mio Gruppo"];
TermSet temaChoice = null;

for (var i = 0; i < group.TermSets.Count; i++)
 {
   if (group.TermSets[i].Name == "Mio Campo")
    {
      temaChoice = group.TermSets[i];
      break;
    }
 }


TaxonomyField tagsField = (TaxonomyField)ctype.Fields.GetField("Mio Campo");


 var results = temaChoice.GetTerms("label_termine", false);
 if (results.Count > 0)
 {
   string TermGuid = Convert.ToString(results[0].Id);
   Guid TermID = new Guid(TermGuid);
   Term ToAddTerm = temaChoice.GetTerm(TermID);
   TaxonomyFieldValue taxonomyFieldValue = new                  TaxonomyFieldValue(tagsField);
   taxonomyFieldValue.TermGuid = ToAddTerm.Id.ToString();
   taxonomyFieldValue.Label = ToAddTerm.Name;
   int[] wssIds = TaxonomyField.GetWssIdsOfTerm(oSite,                  ToAddTerm.TermStore.Id,                                              ToAddTerm.TermSet.Id, ToAddTerm.Id, false, 1);
   if (wssIds.Length>0)
       taxonomyFieldValue.WssId = wssIds[0];
                      taxonomyFieldValueColl.Add(taxonomyFieldValue);
            }

item[tagsField.Id] = taxonomyFieldValueColl.ToString();
item[tagsField.TextField] = taxonomyFieldValueColl.ToString();
item.Update()


mercoledì 19 aprile 2017

Impossibile collegarsi a Sharepoint attraverso un host header

Il problema si verifica se ho aggiunto un host header in IIS sul sito web che ospita un'applicazione Sharepoint e l'ho mappato nel file hosts come 127.0.0.1, In questo caso accedendo al sito mi verranno richieste continuamente le credenziali, ma il login fallirà continuamente.

Sono due le possibili soluzioni:

1 Disabilitare il Loopback Check


Aprre un prompt amministrativo di PowerShell e digitare:

New-ItemProperty HKLM:\System\CurrentControlSet\Control\Lsa -Name “DisableLoopbackCheck” -value “1” -PropertyType dword

Oppure da regedit, navigare fino alla chiave

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa

e creare una chiave dword32 di nome DisableLoopbackCheck e settandone il valore a 1

2 Aggiungere al registry la chiave Multistring BackConnectionHostNames


Da regedit accedere alla chiave

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0

e creare la chiave Mulstring BackConnectionHostNames. Come valore vanno inseriti uno dopo l'altro tutti gli host-header definiti