In a previous SharePoint project, I implemented a few event handlers that get called whenever an item in a list gets changed (or added/deleted). There were a few problems along the way that took a bit of searching before I found solutions. This post documents a few of the things that are good to know.
The event handlers that I implemented where all of the synchronous ItemUpdating kind. There are also asynchronous events, like for instance ItemUpdated, but for the scenario at hand, I wanted to have some special handling depending on certain values of an item.
The event handler is of the form
public override void ItemUpdating(SPItemEventProperties properties).
properties.BeforeProperties[<field name>].ToString() to
properties.AfterProperties[<field name>].ToString(). You can also modify the value of the fields in AfterProperties to affect what is actually stored in the list.
Here comes the first gotcha; the BeforeProperties are only populated for document libraries. If you have an event handler on a custom list, the BeforeProperties collection is empty. So in order to check the current value of a field, you have to use properties.ListItem[<field name>] instead.
Second gotcha; be aware of the internal name of fields. They have a sneaky behaviour in this case. As usual you should use the internal name of the field instead of the display name when accessing the field, i.e. “Evaluation_x0020_Date” instead of “Evaluation Date”. However, you can do properties.ListItem[“Evaluation Date”] to get the current value of the field, BUT to get the new value from AfterProperties, you have to do properties.AfterProperties[“Evaluation_x0020_Date”]. Here comes the even sneakier behaviour; if you try to do properties.AfterProperties[“Evaluation Date”], it doesn’t fail, but returns null. Usually, if you try to access a field that does not exist, an exception is thrown. However, “Evaluation Date” passes as a valid field name, but the value cannot be found.
The third problem I had was related to date fields. In my event handler, I wanted to make sure that a certain date field remained unchanged if some other condition was met. The easiest solution would of course be
properties.AfterProperties[“Decision Date”] = properties.BeforeProperties[“Decision Date”]
As already stated in the first gotcha, the BeforeProperties is not populated for lists, so the statement was revised to
properties.AfterProperties[“Decision Date”] = properties.ListItem[“Decision Date”]
Now, this is still too simple, if you read the gotcha number two, you know that we have to use the internal name. Taking this into account, the third revision of the line is
properties.AfterProperties[“Decision_x0020_Date”] = properties.ListItem[“Decision_x0020_Date”]
This still doesn’t work. Even though all the properties are strings, and it is the same field, the formats of the strings are somehow still incompatible. The data type in this case was a datetime. It turns out that the format that comes out of the ListItem is in the format the SharePoint site uses, while the AfterProperties need the date in ISO8601 format. The fourth and final iteration (that actually works) of the line ended up as
properties.AfterProperties[“Decision_x0020_Date”] = Microsoft.SharePoint.Utilities.SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Parse(properties.ListItem[“Decision_x0020_Date”].ToString()))
Short and concise.





