by matteo
12. aprile 2012 09:46
Una caratteristica di SharePoint molto comoda utilizzabile durante lo sviluppo è rappresentata dagli EventReceiver.
Grazie agli EventReceiver è possibile agganciare del codice personalizzato ad eventi che si scatenano sulle liste o sulle document library di SharePoint quando un elemento viene inserito, aggiornato, eliminato o quando se ne modificano gli allegati.
Stavo sviluppando uno di questi EventReceiver che doveva controllare se alcuni campi di un elemento di una lista erano stati modificati e in caso affermativo impostare un flag in modo da avvisare graficamente l'utente che queste modifiche erano state fatte.
Per controllare se i campi erano stati modificati avevo fatto l'override dell'evento ItemUpdating, che scatta prima che le modifiche fatte all'elemento vengano scritte sul database di contenuto.
Su ItemUpdating andavo a confrontare i valori dei campi che mi interessavano trasformandoli prima in stringhe in modo da poter gestire la comparazione. Per conoscere il valore prima della modifica e quello dopo la modifica usavo, rispettivamente la proprietà ListItem e la proprietà AfterProperties dell'oggetto SPItemEventProperties properties come documentato qui.
Nel dettaglio i campi che dovevo confrontare erano di tipo Testo, Data e Persona (sia a singolo valore che multivalore).
Il codice usato era di questo tipo:
string oldValue = properties.ListItem["FieldName"] == null ?
string.Empty : properties.ListItem["FieldName"].ToString();
string newValue = properties.AfterProperties["FieldName"] == null ?
string.Empty : properties.AfterProperties["FieldName"].ToString();
if (oldValue != newValue) {
// Imposta flag di modifica
}
Testando il funzionamento di questo EventReceiver ho notato delle anomalie; il flag che indicava la modifica dei dati veniva settato anche quando i campi controllati non venivano modificati.
Facendo un po' di test ho scoperto 3 tipologie di comportamenti strani (probabilmente ce ne saranno altri, se li scoprite fatemelo sapere...):
-
AfterProperties NULL
Valore del campo sulla proprietà ListItem (vecchio) corretto, mentre sulla proprietà AfterProperties (nuovo) è uguale a NULL
Purtroppo non sono riuscito a trovare nessuna documentazione in merito e ho ipotizzato che quando ci si trova in questo caso il valore del campo non sia stato modificato.
-
Campi di tipo Person
Sui campi di tipo person il valore del campo sulla proprietà ListItem (vecchio) è nel formato ID;#Nome Completo Utente (es. 1;#Mario Rossi), mentre sulla proprietà AfterProperties (nuovo) viene riportato solo l'ID oppure in alcuni casi viene riportato nel formato ID;#Dominio\UserName (es. 1;#MICROSOFT\mrossi).
In questo caso per risolvere il problema ho tenuto conto solo dell'ID, in questo modo:
if (properties.ListItem["FieldName"].ToString().IndexOf(";#") >= 0) {
property = properties.ListItem["FieldName"].ToString().Substring(0, properties.ListItem["FieldName"].ToString().IndexOf(";#"));
if (properties.AfterProperties["FieldName"].ToString().IndexOf(";#") >= 0) {
if (properties.AfterProperties["FieldName"].ToString().IndexOf(";#") == properties.AfterProperties["FieldName"].ToString().LastIndexOf(";#")) {
afterProperty = properties.AfterProperties["FieldName"].ToString().Substring(0, properties.AfterProperties["FieldName"].ToString().IndexOf(";#"));
}
}
if (afterProperty.Length == 0)
afterProperty = properties.AfterProperties["FieldName"].ToString().Trim();
}
-
Campi di tipo Data/ora
L'ultimo problema riscontato riguardava i campi di tipo Data/ora. Il valore del campo sulla proprietà ListItem (vecchio) è nel formato dd/MM/yyyy hh:mm:ss (es. 12/04/2012 14:30:26), mentre sulla proprietà AfterProperties (nuovo) viene riportato nel formato yyyy-MM-ddThh:mm:ssZ (es. 2012-04-12T14:30:26Z).
In questo caso per risolvere il problema ho convertito come prima cosa i 2 valori in DateTime e poi li ho confrontati.
if (properties.ListItem["FieldName"].GetType() == typeof(DateTime)) {
DateTime dtProperty = Convert.ToDateTime(properties.ListItem["FieldName"]);
DateTime dtAfterProperty = Convert.ToDateTime(properties.AfterProperties["FieldName"]);
property = dtProperty.ToShortDateString();
afterProperty = dtAfterProperty.ToShortDateString();
}
Spero che queste informazioni possano essere utili a qualcuno...