There are a lot of different events that are exposed for us to hook our code into. Unfortunately, WHEN those events get triggered is poorly documented and inconsistent across the SharePoint framework. I wrote this article to list out the different event hooks available and to document my test results when I built some automation into a document library using event handlers. My goal was to have some code run on every document added to the library to modify the field values. I was surprised by how much work was involved in getting it to behave consistently. Hopefully the material here will save you from some of the suffering I went through.
Event Receiver Classes
There are several Event Receiver classes that you can extend from that each get called at different times:
- SPEmailEventReceiver – This class exposes a single event, EmailReceived, that is fired when a list receives a new email item.
- SPItemEventReceiver – Events that happen to items in a list or library (i.e. new item created, item updated, attachment added, file moved, etc.) This is the really important one for document library automation, and is the focus of this article.
- SPListEventReceiver – Events that happen to a list (i.e. new list created, list deleted, field added to the list, etc.)
- SPWebEventReceiver – Events that happen to the website (i.e. new website created, website deleted, website moved, etc.) and the site collection deleted events.
You can also directly add an event handler through the SPEventReceiverDefinition class, but this is usually not necessary for most common tasks.
These are the events you need to hook into in order to perform any kind of automation related to documents being added to the library. There are about 20 events in the SPItemEventReceiver class that you could hook into, you can see the full list at http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spitemeventreceiver_members.aspx, but the main ones we are interested in are those that may get called when a document is being added to a document library.
Different methods of adding a document to the library
SharePoint supports several different paths for adding a document to a document library. Each of these paths triggers events in subtly different ways. I found most of the bugs I ended up working on with the system I built were related to events being called more than once or not being called at all depending on the method used to add the document to the library.
The different ways of adding a document to a library are:
- Through the Upload/Add New Document feature in the web UI.
- Through Office integration by using the SaveAs menu item to change a document’s location in SharePoint.
- Using non-Office programs through the SaveAs menu item to change a document’s location in SharePoint.
- Through a mapped drive or explorer view, either copy and paste, or directly drag a file into the explorer window.
The Testing Setup
I built a stub event handler class that extended the SPItemEventReceiver and logged a message for each event handler that was called. I wired it to my document library and then tried adding documents to the library in various ways to see what got called.
Here are the different sets of events that were called for each test.
When using Office Word SaveAs
ItemAdding – ItemAdded
Office applications seem to have their own integration that avoids calling the ItemUpdating/ItemUpdated methods.
When using NotePad SaveAs
ItemAdding – ItemAdded – ItemUpdating – ItemUpdated – ItemDeleting – ItemDeleted – ItemAdding – ItemAdded – ItemUpdating – ItemUpdated
This was one of the more surprising results for me. I have no idea why the system deletes the first item and then re-creates it. My guess is that it has something to do with how Windows saves things to network drives.
When using MSPaint SaveAs
ItemAdding – ItemAdded – ItemUpdating – ItemUpdated – ItemDeleting – ItemDeleted – ItemAdding – ItemAdded – ItemUpdating – ItemUpdated – ItemUpdating – ItemUpdated – ItemUpdating – ItemUpdated
Yes, It actually called ItemUpdating/ItemUpdated three times when saving from MSPaint. I included this to demonstrate the point that the events called are different depending on which program you use to save the file.
When using the WebUI Upload or Add Item buttons
ItemAdding – ItemAdded
After these initial events you get the item properties screen where the user can enter values for the fields in the library. Then the next sete of events fire…
ItemUpdating – ItemUpdated
Windows Explorer Copy-Paste or Drag-N-Drop
ItemAdding – ItemAdded – ItemUpdating – ItemUpdated – ItemUpdating – ItemUpdated
In my particular case, if I set the field values during ItemAdding/ItemAdded, then the user had the opportunity to override those values when using the WebUI to add a document. However, if I set the values during the ItemUpdating/ItemUpdated events, the values didn’t get set at all when a user saved a file with an Office application. I came up with two solutions to this issue:
Force ItemUpdating to be called.
By adding a properties.ListItem.SystemUpdate(false) to the ItemAdded event, you can force the framework to invoke the ItemUpdating/ItemUpdated methods … even when MS Word is used to save the file. Then you just set the field values in the ItemUpdating method as usual.
Modify the Item Properties Form
You can override the Edit Properties form on document library items so that it doesn’t allow the user to set values for the fields you want. Then the user can’t modify/override the values you set in your code during the ItemAdded event.