Search This Blog

Saturday 19 January 2013

Item Updating and Item Updated Events fire twice in SharePoint 2010



Hi All,
                This is my first post in 2013, here I just want to discuss about Event Receivers in SharePoint 2010 (SPItemEventReceiver class) and an important factor with the Event Receivers. Let me start with “What is an Item Event Receiver”

What is an Item Event Receiver?
                Item Event receivers in Microsoft SharePoint 2010 enable your custom code to respond when specific actions occur on a SharePoint List Item. Instead of writing more paragraphs I can use tabular to explain, I think this will be easy to understand.

Event Name
Synchronous
Description
Item Events
ItemAdding
Yes
Runs before an item is added to the list.
ItemAdded

Runs after an item has been added to the list.
ItemDeleting
Yes
Runs before an item is deleted from the list.
ItemDeleted

Runs after an item has been deleted from the list.
ItemUpdating
Yes
Runs before an item is updated in the list.
ItemUpdated

Runs after an item has been updated in the list.
Check-In Events
ItemCheckingIn
Yes
Runs before an item is checked in.
ItemCheckedIn

Runs after an item has been checked in.
ItemCheckingOut
Yes
Runs before an item is checked out.
ItemCheckedOut

Runs after an item has been checked out.
ItemUncheckingOut
Yes
Runs before an item is un-checked out.
ItemUncheckedOut

Runs after an item has been un-checked out.
File Events
ItemFileConverted

Runs before a file in a doc library is converted to a different file type.
ItemFileMoving
Yes
Runs before a file is moved.
ItemFileMoved

Runs after a file has been moved.
Attachment Events
ItemAttachmentAdding
Yes
Runs before an attachment is added to an item.
ItemAttachmentAdded

Runs after an attachment has been added to an item.
ItemAttachmentDeleting
Yes
Runs before an attachment is deleted from an item.
ItemAttachmentDeleting

Runs after an attachment has been deleted from an item.

As you look through this list, you should notice that events have two types of endings: 

1. Events ending in ING:
i. Examples include ItemAdding, ItemDeleting, ItemUpdating, etc.
ii. These events occur BEFORE the action takes place. This means that you have a chance to modify the item or cancel the operation before it occurs.
iii. These event handlers run synchronously – they occur in order and one must complete before the next is run.
iv. You may be able to modify property values in the event handler.
a.       Each event method has a SPItemEventProperties parameter named properties. If you wish to modify a property value on the list item during the event, the value should be updated in AfterProperties property of the properties parameter. SharePoint reads these values from the event parameter and modifies the item accordingly when the actual operation runs (e.g. the actual Add / Update operation for which the Adding / Updating event is being fired). Do NOT try to manually get the list item in code and update a property on it because the optimistic locking mechanism in SharePoint may throw an error later on when the operation associated with the event to which you are responding attempts to complete.

2. Events ending in ED:
i. Examples include ItemAdded, ItemDeleted, ItemUpdated, etc.
ii. These events occur AFTER the action takes place. This means that you can respond to the event but you cannot cancel it or modify anything about it.
iii. These events handlers may run synchronously or asynchronously depending on how they are configured. Asynchronous operations may occur in any order and complete in order.
iv. Property modification is not available in an asynchronous event handler (even if it is running synchronously).
a.       Although asynchronous events expose a SPItemEventProperties parameter named properties just like their synchronous counterparts, remember that the operation has already completed so you cannot modify anything in the properties parameter (well, you can, but it doesn’t do anything). Additionally, the properties parameter may not be populated with information that you would tend to expect to be present. 

Note: One major thing you should know about the SPItemEventReceiver class is that while you can implement multiple list item event handlers in a single class, SharePoint instantiates a new instance of that class for each individual event it needs to handle. What this means is that you cannot store data in instance-level variables and share that data between event handlers. For example, if you define an instance level variable in the class to store data in the ItemUpdating event, then try to access that data in the ItemUpdated event, you will find that the data is not there when you go to check it in the ItemUpdated event. This is because you have two classes – one that is handling the ItemUpdating event and in which the instance level variable is set, and one that is handling the ItemUpdated event in which the instance level variable is not set.

Item Updating and Item Updated Events fire twice

                As per the first look of Developers, we say simply, Item Updating and Item Updated events are fire twice when we adding a document to a document library that has the Require Check Out option enabled. This is not either issue with SharePoint or issue with Custom Code.  To understand why this is happening, let’s first look at what happens when the user adds a document to the library when the Require Check Out option is disabled:
  • User clicks on the Add a Document link
  • SharePoint displays the Upload a Document dialog
  • User uploads the Document to SharePoint
  • SharePoint fires the ItemAdding Event
  • SharePoint adds the document to the Library
  • SharePoint fires the ItemAdded event
  • SharePoint displays the file in the library

So the net result of this is that the document is uploaded and the ItemAdding and ItemAdded events have fired, which is pretty much what you would expect. Next, let’s look at what happens when the user adds a document when the Require Check Out option is enabled. 

  • User clicks on the Add a Document link
  • SharePoint displays the Upload a Document dialog
  • User uploads the Document to SharePoint
  • SharePoint fires the ItemAdding Event
  • SharePoint adds the document to the Library
  • SharePoint fires the ItemAdded event
  • SharePoint displays the property editing screen to the user
  • User edits any properties they wish to change and clicks the Save button
  • SharePoint fires the ItemUpdating event (first time it is fired)
  • SharePoint sets any document property field entered in the property editor dialog
  • SharePoint fires the ItemUpdated event (first time it is fired)
  • SharePoint now begins the process of automatically checking in the document
  • SharePoint fires the ItemUpdating event (second time it is fired)
  • SharePoint fires the ItemCheckingIn event
  • SharePoint fires the ItemUpdated event (second time it is fired)
  • SharePoint fires the ItemCheckedIn event
The first time the ItemUpdating and ItemUpdated events fire it is in response to the document properties changing. The second time they fire it is in response to the document being checked in. It appears as though they are firing twice in this situation because SharePoint is updating the properties on the document and then checking it in on the same request. If you were to check the document out and edit the properties on the document, you would see the ItemUpdating and ItemUpdated events fire once. Later on, when you checked the document in, you would see those events fire again. So the double-event firing isn’t a bug, it’s just a result of the automatic check-in that occurs when you first add a document to a document library.

Note:    when the property editor dialog displays, the user has the option to cancel out of the dialog. If the user opts to cancel, then only the ItemAdding and ItemAdded events will have fired and the document will be left in a checked out state.
The ItemUpdating and ItemUpdated events that fire in response to the properties being edited from the dialog will always occur, even if the user is not entering or changing any of the values.
Turning Off the Require Check Out Option
One option for fixing the double-event firing issue is to simply turn it off. You can locate the setting using the following instructions:
  • Click on a list in the left navigation menu (or otherwise get into a list)
  • Click the Library tab in the Ribbon
  • Click Library Settings button in the Library Tab
  • This will take you to the list information screen
  • Click the Versioning settings link
  • The Require Check Out radio button should appear in the list of settings
Programmatically Determining the Cause of ItemUpdating and ItemUpdated Firing 

    Turning off the Require Check Out option is a great quick fix if you don’t require the item to be checked out in order for it to be edited. But that option exists to be used, and some people really do need it. If you find yourself in this situation, then you’ll have to solve the problem in code. Fortunately, there is a relatively simple way to check whether the ItemUpdating and ItemUpdated events are firing in response to a check-in outlined in Knowledgebase Article 939307. You just have to check to see if the vti_sourcecontrolcheckedoutby property on the item was cleared:

Code:
public override void ItemUpdating(SPItemEventProperties properties)
{
    
if (properties.AfterProperties["vti_sourcecontrolcheckedoutby"] == null
        
&& properties.BeforeProperties["vti_sourcecontrolcheckedoutby"] != null)
    
{
        
//Code to run if event trigged by a check-in
    
}
    
else
    
{
        
//Code to run if event trigged by something else
    
}
}

This code is using the BeforeProperties and AfterProperties on the properties parameter to see what the value of the vti_sourcecontrolcheckedoutby property on the item was before the update occurred, and what it will be after the update has completed. The vti_sourcecontrolcheckedoutby property identifies who the item is currently checked-out to. As such, if the item is being checked-in, the BeforeProperties will contain a value for the property and the AfterProperties will not. It’s a pretty simple fix, but we can definitely make it a bit more reusable for everyone on a development team and reduce the hassle of having to remember the specifics about how to run the check in their ItemUpdating and ItemUpdated event handlers.

Creating a Base Class for Event Receivers 

Please refer and follow steps given in the following post to create a base class for Event Receiver http://www.simple-talk.com/dotnet/.net-tools/managing-itemupdating-and-itemupdated-events-firing-twice-in-a-sharepoint-item-event-receiver/