SharePoint list event receiver e problemi con Afterproperties

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...):

  1. 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.

  2. 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();
    }
    
  3. 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...

Tags: ,

About the author

Something about the author

Month List

Page List