Our Blog
  • Andreas Finne (gravatar)

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

    The properties object contains the collections BeforeProperties and AfterProperties that helps you to find out what has changed for your item,  i.e. compare
    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.

    • axiom (11.5.10 15:00)

      Great work man, great.

    • Ryan Wentzel (18.5.10 18:40)

      Working with the SharePoint Object Model can be so frustrating at times. Thanks for the tips.

    • csr (1.6.10 17:21)

      Hi Im doing an ItemAttachmentAdding event and I have to put a column value to "1" when the event happens.

      I have tried without success:


      properties.AfterProperties[NAME] = "1";
      properties.ListItem.Update();

      I hope you can help me.

    • Andreas Finne (14.6.10 08:37)

      Inside a synchronous event handler (-adding) you shouldn't have to do ListItem.Update(), since that is handled by SharePoint afterwards by taking the AfterProperties. On the other hand, in an asynchronous event handler (-added), you have to do ListItem.Update(), and modify the item directly instead of modifying the AfterProperties collection.

      So, without having any more information that you provided, I suggest that you try without the Update() at the end.

    Leave a reply

    Name (required)
    Website