Tuesday, June 7, 2011

SharePoint: Disable Event Receiver From non-receiver code

When we are in List Item Event Receiver code, we can modify/update the same item which will fire the event receiver again. For disabling event receiver to get fired again we can use the property ‘’ as shown below:

public class TestEventReceiver:SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
//disable event receiver firing
EventFiringEnabled = false;


//do something



//enalbe event receiver firing
EventFiringEnabled = true;

}
}
Figure 1: Sample code to enable/disable event receiver firing inside event receiver handler.

However, if you are in a webpart and want to modify an item but don’t want to fire event receiver, then? Don’t worry there’s a way out. I’ll explain this today.

 

What happens when Event Receiver disabled?

When you disable event receiver, SharePoint internally set a data field in current Thread. So if you can set your current’s thread’s data to the required value before/after updating item, you can control the event receiver. However, setting current thread data manually might be risky and I’ll not use that path. Rather I’ll show how we can use existing power of ‘SPEventReceiverBase’ to control event receiver firing.

 

Create your own Event Receiver Controller

I’ve create a custom class inherited from ‘SPEventReceiverBase’. From this base class I get a properties ‘EventFiringEnabled’ which allows me to control the event receiver firing. The following code snippet shows my custom EventReceiverManager:

public class EventReceiverManager : SPEventReceiverBase, IDisposable
{
public EventReceiverManager(bool disableImmediately)
{
EventFiringEnabled = !disableImmediately;
}

public void StopEventReceiver()
{
EventFiringEnabled = false;
}
public void StartEventReceiver()
{
EventFiringEnabled = true;
}

public void Dispose()
{
EventFiringEnabled = true;
}
}
Figure 2: A EventReceiverManager custom class to control event receiver firing.

The code snippet above is derived from SharePoint’s SPEventReceiverBase to use the ‘EventFireingEnabled’ property.

 

Now you can use this EventReceiverManager to control the event receiver. To stop firing the event receiver on any changes, you need to wrap the code block inside EventReceiverManager as shown below:

using (var eventReceiverManager = new EventReceiverManager(true))
{
var list = GetList("listName");
var listItem = list.GetItemById(itemId);
listItem["field"] = "value";
listItem.Update();
}
Figure 3: How to use EventReceiverManager to disable event receiver firing.
 

As shown above even if he list has event receiver for ItemUpdated/ItemDating the event receiver will not get fired because of putting the code in EventReceiverManager block. Please notice of ‘using’ block, as soon as you leave the ‘using’ block, the event firing in enabled automatically. This is because in Dispose method of EventReceiverManager I’ve enabled the event firing.

6 comments:

  1. Thank you, this seems to be just the code I needed.

    ReplyDelete
  2. Thanks. This is very useful tip.

    ReplyDelete
  3. Very nifty little tip! Just for my interest's sake, can you explain how your EventReceiverManager class actually "hooks in" to the event receivers that are triggered inside the using block? And if I were to update multiple lists inside the using block, would event firing be disabled on ALL of the event receivers?

    ReplyDelete
  4. @Nick, it's all about threading. Setting the EventFiringEnabled property, set a custom value in the current thread. So as long as you do all your work with the current thread, you should get the event firing active/deactived.

    ReplyDelete
  5. Bad example of code. Dont use this if you professional.

    ReplyDelete
    Replies
    1. Terrible example of a comment. If you are going to assert that there is something wrong, explain your reasons

      Delete