Update a SharePoint List Item in an ItemUpdated Event, Without an Endless Loop

Jul 17 2012

There may come a time in your SharePoint development that you will need to update a list item during an ItemUpdated event. For instance, have a look at this code:

        public  override  void  ItemUpdated(SPItemEventProperties  properties)
        {
            base .ItemUpdated(properties);
            SPListItem  listItem = properties.ListItem;
            listItem["Title" ] = "A cool new title!" ;
            listItem.Update();
        }

 

In this ItemUpdated event, we are simply assigning the current ListItem to a new SPListItem object, changing its "Title" property, and updating it. Pretty simple. However, this simple piece of code will cause an endless loop, as each time you call listItem.Update(), the ItemUpdated event receiver fires. As you can see, we need a way to prevent this loop from occuring.

Luckily there is an easy and elegant solution with a little custom code. We'll create a class called DisabledEventsScope:

     class  DisabledEventsScope  : SPItemEventReceiver , IDisposable 
     {
         // Boolean to hold the original value of the EventFiringEnabled property 
         bool  _originalValue;
 
         public  DisabledEventsScope()
         {
             // Save off the original value of EventFiringEnabled 
             _originalValue = base .EventFiringEnabled;
 
             // Set EventFiringEnabled to false to disable it 
             base .EventFiringEnabled = false ;
         }
 
         public  void  Dispose()
         {
             // Set EventFiringEnabled back to its original value 
             base .EventFiringEnabled = _originalValue;
         }
     }

 

This class is simple and to the point.  We inherit SPItemEventReceiver and IDisposable, SPItemEventReceiver will give us access to the base properties in the event receiver and IDisposable will give us a Dispose method (which comes in handy in a moment).

SPItemEventReceiver has a property called EventFiringEnabled, which simply indicates whether event firing is enabled.  We can turn this off to prevent our loop from occuring.  First, we declare a boolean to hold the original value of the EventFiringEnabled property.  Now, in our constructor we save off the EventFiringEnabled value, then set it to false.  Next, in our Dispose method, we simply set the value back and you're done.

Now you may ask, why not just set it to false in the constructor and set it to true in the Dispose.  This will most likely work for 99.9% of all implementations, but why take the risk.  There may be other code working some magic here as well, and by saving off the value and setting it back you do not interfere with anything else that may be going on.

Now, implementing this code is even more simple.  All we need to do is wrap our previous code in a Using statement:

        public  override  void  ItemUpdated(SPItemEventProperties  properties)
        {
            base .ItemUpdated(properties);
            using  (DisabledEventsScope  scope = new  DisabledEventsScope ())
            {
                SPListItem  listItem = properties.ListItem;
                listItem["Title" ] = "A cool new title!" ;
                listItem.Update();
            }
        }
 

Viola! Now once the listItem.Update() fires, we are inside the scope of our DisabledEventsScope class which has disabled event firing.  Once our update takes place, event firing will be restored and everything works appropriately.

Enjoy!

About the Author

Brandon Atkinson's picture

Brandon Atkinson is a Manager with the Microsoft Practice at CapTech. He is currently focusing on SharePoint, ASP.NET MVC, and is a frequent contributor on the SharePoint Forums.

 

Disclaimer

The words and opinions expressed here are those of each article's respective author, and do not necessarily represent the views of CapTech Ventures.