Let’s say we have a wiki library which has a event receiver attached to the “ItemAdded” event. We write some piece of code that is supposed to fire when an item is added. For the sake of simplicity, let’s say we want to audit who created a new wiki page, so we log it in some way. After writing & deploying the code what we observe is that not only is the “ItemAdded” event fired but also the “ItemUpdated” event fires. Why does SharePoint do that?
Well, the cause is pretty obvious “a” wiki page is created and right after it’s created it’s opened in an edit mode, hence the two consecutive events. Nice article by Damon BTW in the context (Managing ItemUpdating and ItemUpdated Events Firing Twice in a SharePoint Item Event Receiver).
We just want to log\track “a” single event, since it’s very much possible that the user may not want to edit the page or may just cancel it out.
Q:how do we conditionally fire the event?
One possible solution:
Before we look at the possible solution, couple of facts:
- As you may know that each event (ItemAdding, ItemAdded, etc. check this out for the complete listing of SharePoint Events) generates a new “instance” of the class that extends the base class SPItemEventReceiver.
- The ItemAdded event is always going to fire before the ItemUpdated event, irrespective of the Synchronization property.
The issue is to persist the fact that a new wiki page is being added and preserve it between the “ItemAdded” event and the “ItemUpdated” event and then based on that information, conditionally fire the ItemUpdated event. Here is where a “Key-Value” based collection can come to our rescue.
Here is a high level mention of the steps…
- Create a static variable of a collection type for e.g. Hashtable
- Use the “ListItemId” property from the event args (default name, properties) and store it as the “key” in the variable created in step 1; the value part being a flag or status of some kind…for e.g. I used “new”
- In the “ItemUpdated” event use the same variable created in step 1 and then get the flag\status using the same “ListItemId” property from the event args. Once the value if available, we can then do the conditionally processing.
So even though, there are multiple events firing in there(which is technically correct), we can still isolate them and conditionally do some processing. One important thing to remember is that once we have used the value in the “ItemUpdated” event from the collection variable, we need to delete that so that the variable is light-weight and doesn’t cause unnecessary load.
Sample (incomplete) code:
public class EventReceiver1 : SPItemEventReceiver
static Hashtable listItemStatus = new Hashtable();
public override void ItemAdded(SPItemEventProperties properties)
Debug.WriteLine(“wiki – item added at: ” + DateTime.Now);
public override void ItemUpdated(SPItemEventProperties properties)
string listIdStatus = EventReceiver1.listItemStatus[properties.ListItemId] == null ?
if (!String.IsNullOrEmpty(listIdStatus) &&
String.Compare(listIdStatus, “new”) != -1)
Debug.WriteLine(“wiki – new item added; do nothing at: ” + DateTime.Now);
//very important to get rid of it – can be moved to finally block as well
Debug.WriteLine(“wiki – regular item updated at: ” + DateTime.Now);
The same logic can be extended for other lists or libraries as appropriate to their respective behavior for the various events.
Hope this helps…