Posts
163
Comments
179
Trackbacks
5
febbraio 2009 Blog Posts
SharePoint: aggiungere e rimuovere modifiche al web.config tramite feature


L’argomento è trattato in tanti post, ma personalmente ho trovato molte difficoltà a reperire le giuste informazioni e a sviluppare una soluzione pienamente funzionante. Quindi cerco di fare chiarezza per futura memoria mia e per chi ne avrà bisogno.

L’esigenza è molto semplice: modificare il web.config di SharePoint con l’aggiunta di parametri, sezioni o modificando il valore di semplici attributi. Il caso che forse più comune è quello di aggiungere parametri alla sezione <appSettings> che solitamente non è nemmeno presente nel web.config di SharePoint.

L’esempio presentato in questo post tratta proprio l’aggiunta di un parametro alla sezione <appSettings>.  Supponendo di aver già impostato la nostra feature con i vari eventi e supponendo di voler aggiunere il parametro quando la feature viene attivata e rimuoverlo quando la feature viene disattivata, dovremo prendere in considerazione i due eventi FeatureActivated e FeatureDeactivating.

In fase di attivazione il codice da eseguire sarà questo:

   1: public SPWebConfigModification createModification(String paramName, String value, String ownerID)
   2: {
   3:   SPWebConfigModification modification = new SPWebConfigModification("add[@key='" + paramName + "']", "configuration/appSettings");
   4:   modification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
   5:   modification.Value = "<add key=\"" + paramName + "\" value=\"" + value + "\" />";
   6:   modification.Sequence = 0;
   7:   modification.Owner = ownerID;
   8:   return modification;
   9: }
  10:         
  11: public override void FeatureActivated(SPFeatureReceiverProperties properties)
  12: {
  13:     SPWebApplication webApp = SPContext.Current.Site.WebApplication;
  14:     // Ripulisco le modifiche precedenti se presenti
  15:     webApp.WebConfigModifications.Clear();
  16:     // Per sezioni che includono altri figli devo usare EnsureSection.
  17:     // questo fa si che la sezione venga creata se non esistente
  18:     SPWebConfigModification modification = new SPWebConfigModification("appSettings", "configuration");
  19:     modification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureSection;
  20:     modification.Value = "appSettings";
  21:     modification.Sequence = 0;          
  22:     // In questo caso il Guid è settato ad un valore casuale in modo che la sezione non 
  23:     // sarà rimossa in fase di disinstallazione potendo essere usata da altre applicazioni
  24:     modification.Owner = Guid.NewGuid().ToString();
  25:     // Aggiungo le modifiche
  26:     webApp.WebConfigModifications.Add(modification);
  27:  
  28:     // Aggiungo un parametro 
  29:     webApp.WebConfigModifications.Add(createModification("Param1","Value1", properties.Feature.DefinitionId.ToString()));
  30:  
  31:     // Salvo le modifiche sul web.config
  32:     webApp.Update(); 
  33:     webApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();           
  34: }

Da notare che come prima cosa viene creare la sezione <appSettings> se non esistente. Dato che si tratta di una sezione e dato che non vogliamo sovrascriverla se già presente utilizzeremo il tipo EnsureSection e come owner utilizzeremo um Guid generato casualmente.
Molta attenzione va fatta invece nell’aggiunta dei parametri alla sezione <appSettings>. Infatti il nome della SPWebConfigModification deve essere l’XPath che identifica univocamente il nodo all’interno della sezione padre.
Se il nome non viene impostato correttamente otterremo due side-effect:

  1. il parametro non sarà rimosso in fase di disattivazione della feature;
  2. se il parametro è già presente, verrà creato un doppione.

La rimozione delle modifiche eseguite è un’operazione molto più semplice. La funzione che sto utilizzando è quella descritta in questo post:

   1: public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
   2: {
   3:   SPWebApplication webApp = SPContext.Current.Site.WebApplication;
   4:   Collection<SPWebConfigModification> oCollection = webApp.WebConfigModifications;
   5:   int iStartCount = oCollection.Count;
   6:   // Elimino solo le modifiche inserite dalla feature corrente (verifico attraverso l'ID)
   7:   for (int c = iStartCount - 1; c >= 0; c--)
   8:   {
   9:     SPWebConfigModification oModification = oCollection[c];
  10:     if (oModification.Owner == properties.Feature.DefinitionId.ToString())
  11:       oCollection.Remove(oModification);
  12:   }
  13:   // Se è stato effettivamente eliminato qualcosa, faccio l'update
  14:   if (iStartCount > oCollection.Count)
  15:   {
  16:     webApp.Update();
  17:     SPFarm.Local.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
  18:   }
  19: }

Sostanzialmente si cicla tra tutte le modifiche presenti e si rimuovono solo quelle che hanno l’owner identico all’ID della Feature corrente.
Alla prossima!

posted @ mercoledì 25 febbraio 2009 15:47 | Feedback (4)
Crash inaspettato dell’add-in WSPBuilder in Visual Studio 2008


Ormai per me che sviluppo molto su SharePoint, l’add-in di WSPBuilder per Visual Studio 2008 è diventato un must. Lo sto usando con profitto in tanti progetti e la sua gestione del deploy a mio giudizio non ha eguali.

Comunque ieri installando l’add-in su di una nuova macchina virtuale con Visual Studio 2008 + SP1 ho riscontrato un crash inaspettato che non avevo mai incontrato su altre macchine. Sostanzialmente Visual Studio 2008 in fase di startup andava in crash sistematicamente. Disinstallando l’add-in tutto tornava a funzionare. Reinstallando, stesso errore.
Sull’event-viewer l’unico indizio riportato è il seguente:

Faulting application devenv.exe, version 9.0.21022.8, stamp 47317b3d, faulting module msenv.dll, version 9.0.21022.8, stamp 47317c00, debug? 0, fault address 0x000b4210.

Cercando su Google ho trovato sul forum del progetto su Codeplex un post in cui viene segnalato lo stesso errore, anche se viene riscontrato su Windows Server 2008 (nel mio caso il sistema operativo è Windows Server 2003). Purtroppo nel post non veniva data nessuna risoluzione.

Nel mio caso la situazione si è risolta semplicemente reinstallando Visual Studio 2008 + SP1. Non so se possa essere una risoluzione generalizzata al problema, andrebbe verificato in più casi.
Se qualcuno avesse trovato una soluzione più veloce e immediata è pregato di farsi vivo (magari sul forum del progetto per rendere la cosa pubblica).

posted @ mercoledì 25 febbraio 2009 09:53 | Feedback (0)
SharePoint, event receiver e WebService


Oggi mi è capitato un problema “particolare” nella realizzazione e successivo utilizzo di un event receiver legato ad una document library.
Lo scenario è questo: Windows SharePoint Service e un event receiver legato ad una document library. Niente di più facile. Armato del mio fedele Visual Studio e del mio WSPBuilder, in men che non si dica ho buttato su un piccolo progettino di test.

Tutto funziona correttamente. Andando in debug e testando l’inserimento di un documento da SharePoint, Office, risorse di rete, ho verificato che gli eventi vengono sempre agganciati correttamente. Questo fino a che non ho testato un web service sviluppato da terze parti. Il web service in questione non fa nulla in particolare. E’ installato sulla stessa macchina di SharePoint, e lavora direttamente sul modello degli oggetti di SharePoint andando a recuperare un oggetto SPFolder e aggiungendo un nuovo documento.

In questo caso nessun evento viene lanciato, mentre il file viene correttamente inserito all’interno della document library. Consultando il sempre fedele Google, ho scovato questo post in cui mi ha fatto pensare questa frase:

It seems like the Event Handler of SharePoint only trigged in a Context environment ( in the w3wp.exe process, that means the WebPart, the WebApplication, the Web Services, or the Event Handler it self).
It cannot trigged in a console application, because it's not running under the "web". I think it's by design......

Nel mio caso non si tratta di un’applicazione console, ma comunque il discorso che viene fatto è più generale. Andando a controllare, ho notato che effettivamente il web service girava sotto un application pool custom, diverso da quello di SharePoint. Quindi non girava nel contesto di SharePoint. Provando a modificare l’application pool e settando quello usato da SharePoint tutto torna magicamente a funzionare.

Non ho verificato cosa succede in caso di applicazioni diverse, quali console application o servizi Windows.
Che dire, buono a sapersi!

posted @ mercoledì 18 febbraio 2009 23:09 | Feedback (0)
SharePoint: bug “irrisolvibile” nel collegamento di un calendario ad Outlook 2003?


Ieri mentre ero da un cliente, ho notato un comportamento strano: un nuovo elemento aggiunto al calendario di SharePoint 2007 ( o WSS 3.0) e definito come “all-day” viene visto su Outlook 2003 totalmente sballato. Il problema è ben conosciuto e riportato nella KB 919042.

Mi lascia un po’ perplessa la “soluzione”:

… Windows SharePoint Services 3.0 includes enhanced integration with Microsoft Office Outlook 2007. You can use Outlook 2007 to fully interact with information that is stored in Windows SharePoint Services 3.0….

Ma era proprio impossibile da risolvere? Ho capito che Outlook 2003 è molto datato, ma spesso e volentieri è quello che si trova andando a lavorare presso i vari utenti finali (o almeno questa è la mia esperienza personale).

Se qualche “anima pia” avesse un workaround, gliene sarei molto grato.

P.S. Il workaround “installa Outlook 2007” non è valido!

posted @ venerdì 13 febbraio 2009 14:04 | Feedback (4)
Abilitare l’intellisense per SharePoint su Visual Studio 2008


L’intellisense è sempre un bell’aiuto quando si sviluppa con Visual Studio. E allora perchè non averlo abilitato anche mentre ci si diletta con features, solution, element e compagnia bella? Detto fatto: in questo post viene spiegato come abilitare l'intellisense per SharePoint utilizzando Visual Studio 2008.
Semplice e funzionante! Buon intellisense a tutti.

posted @ lunedì 9 febbraio 2009 23:48 | Feedback (0)
jQuery: simulare il tasto TAB con l’Invio


Supponiamo di avere una pagina web qualunque e di voler simulare la pressione del tasto TAB con l’Invio. La richiesta mi è stata fatta da un cliente e in particolar modo dalla persona deputata al data-entry che, dovendo operare in modo molto veloce, preferisce usare il tastierino numerico e avrebbe preferito usare l’Invio al posto del Tab per spostarsi tra i vari campi da riempire.

Come realizzare tutto ciò? Il buon jQuery ci viene in aiuto e, considerando esclusivamente i soli campi input è possibile utilizzare lo script seguente:

   1: textBoxes = $("input:text");
   2: $(textBoxes).keydown(checkEnter);
   3:  
   4: function checkEnter(event) {
   5:     if (event.keyCode == 13) {
   6:         index = textBoxes.index(this);
   7:         if (textBoxes[index + 1] != null) 
   8:         {
   9:             nextCtrl = textBoxes[index + 1];
  10:             nextCtrl.focus();
  11:             nextCtrl.select();
  12:         }
  13:         else 
  14:         {
  15:             nextCtrl = textBoxes[0];
  16:             nextCtrl.focus();
  17:             nextCtrl.select();
  18:         }
  19:         event.preventDefault();
  20:         return false;
  21:     }
  22: }

Nel mio caso recupero tutto i controlli input di tipo text, ma ovviamente è possibile selezionare solo gli elementi con una certa classe.

posted @ martedì 3 febbraio 2009 10:56 | Feedback (0)
News
Se volete sapere con chi avete a che fare eccomi qui in uno "scatto" lavorativo.

La mia foto

Logo MCAD
Logo MCTS