Prash's Blog

SharePoint SPItemEventReceiver ItemUpdating and ItemUpdated being called multiple times July 30, 2009

Filed under: SharePoint — prazjain @ 5:04 pm
Tags:

Problem : SPItemEventReceiver’s ItemUpdating and ItemUpdated methods are called twice! (to be precise)

And if you have Update() or SystemUpdate() call on the document / item, this leads to getting an exception message on screen about “XYZ has already been modified”. This happens due to race condition between the two threads when updating the document / item.

Background

In SharePoint, an event receiver can be hooked to a SPList to listen to any events occuring on the SPList.

This is how you do it :

SPWeb spWeb = GetSPWebInstance();
// assuming that you have a document library by name of "My List"
SPList sharedDocuments = web.Lists["My List"];
// attach a ItemUpdated event.
SPEventReceiverDefinition spEventReceiverDef = sharedDocuments.EventReceivers.Add();
spEventReceiverDef.Class = "Fully.Qualified.Class.Name";
spEventReceiverDef.Assembly = "AssemblyName, Version=x.x.x.x, Culture=neutral, PublicKeyToken=thePublicKeyToken"
spEventReceiverDef.Sequence = 5000; // put any number here
spEventReceiverDef.Type = SPEventReceiverType.ItemUpdated;
spEventReceiverDef.Update();

To attach an ItemUpdating event receiver, all you need to do it replace the type from SPEventReceiverType.ItemUpdated to SPEventReceiverType.ItemUpdating, and ofcourse the class / assembly information if you have the implementation in a different class / assembly.

ItemUpdating gets called synchronously just before an item is updated. And ItemUpdated gets called after the item is updated.

Cause

When force checkout is enabled on document library, this is how the document editing works :

When you checkout a document for editing, a local copy of the document is created that saves all the changes made by the user. At the time of checking-in the document, this local copy updates the original copy (even if there are no changes), then there is another request that does check-in on the document.

This is the reason why ItemUpdating and ItemUpdated are called twice (once for each step of check-in process).

Solution

A Property : “vti_sourcecontrolcheckedoutby” is provided that can be used to distinguish if the update is because of check-in or due to other reasons.

If this property exist in BeforeProperties and not in AfterProperties of SPItemEventProperties instance then it means that the callback is for item check-in event, else it is for event other than item check-in.

So if you have a piece of code that you want to be executed only when the check-in is done then enclose it in a conditional statement like this :

public override void ItemUpdated(SPItemEventProperties properties)
 {
// perform actions only if the update event is triggered by check-in
 if (properties.AfterProperties["vti_sourcecontrolcheckedoutby"] == null &&
 properties.BeforeProperties["vti_sourcecontrolcheckedoutby"] != null)
 {
// your code goes here
}
else
{
//ignore
}
}

Putting your code block in correct conditional section would make sure that your code gets executed for the check-in event callback.

Advertisements
 

One Response to “SharePoint SPItemEventReceiver ItemUpdating and ItemUpdated being called multiple times”

  1. msbuzzz Says:

    Hi prazjain, in what type of project I should create an event receiver, and how do I mention on which Item changed event I should Update a column? Thank You


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s