Wednesday, April 8, 2015

SharePoint - Errore javascript nel file WebResource.axd

Non so dire perché, né spiegarlo o trovare traccia del motivo per cui si presenta, ma ogni tanto, non su tutti i browser, non a tutti gli utenti, e neppure allo stesso utente nella stessa sessione di navigazione, però in pagine particolarmente personalizzate lato client (tramite jquery e javascript di varia forma), viene fuori un errore javascript

'Event' is undefined

normalmente in una delle righe del file WebResource.axd.
In alcune circostanze, non è neppure bloccante, in altre invece blocca l'esecuzione di altri javascript (soprattutto per browser datati, ad es IE7-8)

Proviamo a risolvere o aggirare il problema.

Eseguendo il debug di IE l'errore non si presenta.
Il che dà conferma alla teoria che l'osservazione modifica lo stato (fisica in background), ma non ci aiuta.

Entrando però in debug al momento dell'errore, ecco che abbiamo un'eccezione in questa funzione, dentro il WebResource.axd (riga 184 circa):

function Menu_HideItems(items) {
    if (document.body.__oldOnClick) {
        document.body.onclick = document.body.__oldOnClick;
        document.body.__oldOnClick = null;
    }
    Menu_ClearInterval();
   
if (!items || ((typeof(items.tagName) == "undefined") && (items instanceof Event))) {        items = __rootMenuItem;
    }

...


Mi sono fermato dal capirne i motivi: la funzione viene chiamata dall'evento document.body.onclick, il che fa pensare che sia per chiudere eventuali menu aperti, tramite il click, o roba del genere.
Va bene.
Nella mia pagina, serve un evento del genere? Se la risposta è NO, allora aggiriamo con questo codice, che ho messo nel $(document).ready.

//to prevent error on webresource.axd
var oldMenu_HideItems = Menu_HideItems;  
if(oldMenu_HideItems)
{
    Menu_HideItems = function(items)
    {
        try
          {
            return oldMenu_HideItems(items);
          }
        catch(err)
          {

          }
    }
}
//


Di fatto, ridefinisce la funzione, per recuperarla quando viene chiamata e poterla inserire in un try/catch.
Se la funzione non ha eccezioni, va, altrimenti, non fa nulla e non ho più errori javascript nella mia pagina.

E via.

Friday, January 30, 2015

SharePoint 2013 - Issue su Document Set

Abbiamo sperimentato un paio di Issue sulla gestione dei Document Set su SharePoint 2013 (testati e riprodotti su SP Online).
Ecco qui due promemoria per le prossime volte.

Singolo Apice nel Nome del Document Set

A differenza della gestione dei caratteri speciali NON permessi sui nomi dei file, per il Document Set abbiamo la restrizione solo per i seguenti caratteri:

" # % * : < > ? / \ |.

Quindi, apice singolo e & sono permessi nel nome del file.
MA, utilizzando l'apice singolo, in creazione del Document Set non abbiamo problemi: visualizziamo la Welcome Page correttamente.
Se usciamo dal Document Set, e proviamo a rientrarci, invece, abbiamo il comportamento della Cartella: nessuna welcome page...
Se togliamo l'apice dal nome, in Modifica Proprietà, tutto torna alla normalità.

Conclusione: controllate manualmente che NON sia presente l'apice singolo nel Nome del Document Set.


Errore in Welcome Page per Lookup errate

Creiamo un Content Type Document Set con una colonna di tipo Lookup.
Utilizziamo la colonna in visualizzazione nella Welcome Page.
Tutto fila liscio.
Ora, eliminiamo la Lista cui fa riferimento la Lookup, così da renderla "orfana".
[Già in teoria mi aspetterei un messaggio di errore del tipo "questa lista è utilizzata in una lookup, non puoi eliminarla", ma fa lo stesso]

Il nostro content type continua ad avere la lookup, anche se orfana di lista.
Poco male, non possiamo selezionare nessun valore.

Ma, se apriamo la Welcome Page abbiamo un errore, segnalato sulla web part DocumentSetProperties.

Conclusione: Nelle impostazioni del Content Type Document Set, togliamo dalla visualizzazione in Welcome Page la colonna: tutto va a posto.
Meglio ancora, togliamo la Lookup orfana ;-)


(segue)



Tuesday, July 8, 2014

SharePoint 2013 - Filtrare per Eventi Ricorrenti senza i duplicati

La creazione di un evento ricorrente genera tante istanze dell'evento creato, quante sono le date configurate per la ricorrenza.

Esiste la possibilità di visualizzare tutti gli eventi, con le ricorrenze, tramite la vista Calendario e la vista Eventi Correnti.

La vista Tutti gli Eventi mostra invece gli eventi ricorrenti "Parent", quindi i soli item effettivamente inseriti, con la regola di ricorrenza.

Quando modifichiamo una istanza di una ricorrenza, possiamo decidere se modificare tutta la serie o il singolo elemento: scegliendo l'ultima opzione, viene creato un nuovo item (evento), con un suo id, con le stesse regole della ricorrenza, ma "slegato" dalla ricorrenza "Parent" originaria (pur mantenendo un collegamento interno).

Se vogliamo visualizzare solo gli eventi "Parent" originali, senza gli eventi modificati a partire dalla serie (come descritto sopra), dobbiamo filtrare la web part modifiicando, tramite il Designer, la CAML Query.

Identifichiamo il tag <View> e inseriamo nel tag <Query>, il seguente codice:

<Where><Neq><FieldRef Name="EventType"/><Value Type="Integer">4</Value></Neq></Where>

Questo esclude dalla visualizzazione gli eventi con EventType = 4, cioè quelli generati dalla modifica di una singola ricorrenza.

Wednesday, June 18, 2014

SharePoint - Spostare Document Set di grandi dimensioni

Per lo spostamento di Document Set da una libreria ad un'altra occorre tenere conto del contesto in cui si implementa la procedura di spostamento, in particolare se esiste la possibilità che i Document Set contengano documenti di dimensioni superiori ai 10 Mb.

Export/Import

In rete è la soluzione più consigliata, ma attenzione: per file di grandi dimensioni (superiori a 10Mb), funziona solo nel caso di Event Receiver (o Console Application).
Utilizzato in un Timer Job si riceve un errore decisamente incomprensibile, in fase di Export: "Unable to determine the identity of domain".
Questo messaggio ci ha fatto penare un bel po' ed è riferito ad una classe utilizzata dal package di gestione dello stream in fase di esportazione del Document Set (class IsolatedStorage).

//get Document Set Source
DocumentSet documentSet = DocumentSet.GetDocumentSet(itemToMove.Folder);
//get Target List
SPList targetList = web.Lists[docSetListTargetName];
//get content type id for target list 
SPContentTypeId contentTypeId = targetList.ContentTypes["Custom Document Set Name"].Id;
//export in a stream
byte[] documentSetData = documentSet.Export();
//get document set name
string documentSetName = documentSet.Item.Name;

//get folder target
SPFolder targetFolder = targetList.RootFolder;

//Assign all properties
System.Collections.Hashtable propertiesParent = itemToMove.Properties;

//Create new Document Set 
DocumentSet docSet = DocumentSet.Import(documentSetData, documentSetName, targetFolder, contentTypeId, propertiesParent, currentWeb.CurrentUser);

//then go to delete source document set


Folder.MoveTo

Utilizzando questo metodo viene spostato il Document Set con il suo contenuto, qualsiasi peso abbia, come fosse una Cartella (SPFolder) e successivamente, viene convertita in Document Set Content Type.

La cosa buona è che funziona anche per i Timer Job quindi senza problemi di size.

//get Document Set Source
DocumentSet documentSet = DocumentSet.GetDocumentSet(itemToMove.Folder);
//get Target List
SPList targetList = web.Lists[docSetListTargetName];
//get content type id for target list 
SPContentTypeId contentTypeId = targetList.ContentTypes["Custom Document Set Name"].Id;
//set Url of new Document Set in target list
string moveUrl = targetList.RootFolder + "/" + itemToArc.Folder.Name;
//move document set as folder
itemToMove.Folder.MoveTo(moveUrl);
//check new Document Set
SPFolder newDocset = currentWeb.GetFolder(moveUrl);
if (newDocset.Exists)
{
    //Update all fields from source
    foreach (SPField f in itemToMove.Fields)
    {
         if (!f.ReadOnlyField)
         {
              newDocset.Item[f.StaticName] = itemToMove[f.StaticName];
         }
    }
    //IMPORTANT: convert Folder to Document Set 
    newDocset.Item["ContentTypeId"] = contentTypeId;
    newDocset.Item["HTML File Type"] = "SharePoint.DocumentSet";                                                
    //then update
    newDocset.Item.Update();
}
else
{
   // Failed moving the docset or setting ... 
}

//no need to delete source Document Set


Tuesday, June 17, 2014

SharePoint - Il Check-Out e i Documenti Fantasma!

Lo scenario spettrale nel quale i Documenti scompaiono alla vista di tutti, compreso il System Account, ha una spiegazione (quasi logica) e anche una soluzione!

Il Cliente segnala l'impossibilità di salvare un nuovo Documento (nuovo), creato con Word, con un dato nome.
L'utente X accede alla Document Library su cui è impostato check-in/out per modifica.
Clicca su Nuovo Documento, apre Word, modifica il file e, per qualche ragione, NON esegue Check-in.
Chiude Word, oppure si pianta (non raro), o il browser va in errore (ancora meno raro), o qualsiasi altro motivo per cui non viene archiviato il file.

In questo scenario, gli altri utenti non vedono il documento. Nessuno. Solo l'utente X.

L'utente Y crea un nuovo file e lo vuole salvare, chiamandolo come il file creato (e non archiviato) dall'utente X.
MA riceve un messaggio: Non è possibile salvare il file perché l'utente X sta già modificando un documento con quel nome.

Il sistema dice che c'è quel file, ma non si vede e non possiamo sovrascriverlo né modificarlo perché lo fa già utente X. Neppure System Account lo vede, neppure con Power Shell..

L'utente X sembra l'unico che può vederlo.
L'utente X è l'unico che può cancellarlo.
L'utente X può risolvere il problema.

L'utente X è in maternità.

Microsoft ha previsto, fortunatamente (per loro), lo scenario descritto, fornendo la possibilità, nelle configurazioni della Document Library, di visualizzare i documenti che non hanno ancora una versione: ovvero sono stati creati, ma mai ne è stato eseguito un check-in.

Il Link Manage files which have no checked in version è abbastanza esplicativo.


Mostra i file non archiviati, senza versione:

Selezionando un documento e cliccando su Take Ownership of Selection, l'utente corrente ha la possibilità di prendere il possesso dei file, sostituirsi all'utente che non ha eseguito l'archiviazione, e modificare il file.


Risulta quindi, nella library, finalmente il file:



"SharePoint Mystery - The case of the missing documents" racconta la nostra storia
http://www.networkworld.com/article/2346678/microsoft-subnet/sharepoint-mystery--the-case-of-the-missing-documents.html