Posted by mjimison
on September 22, 2011
Content Type,
Event Receiver,
SharePoint /
No Comments
One of the great new features in SharePoint 2010 is the Content Type Syndication Hub, where we can finally achieve global content types. This ability is achieved by creating a site collection that we designate as the hub that pushes content types to web applications that subscribe to it.
Along with the content types and their related site columns, event receivers also come over during this synchronization process. Attaching event receivers directly to a content type is a good way to ensure your code runs wherever the content type is used.
The Issue
I have updated this post to provide detailed instructions on how to reproduce an issue where event receivers in the subscribing site’s content types appear to be removed when a parent content type that they are based off of, which is in the syndication hub, gets updated with additional event receivers.
Here are the steps to reproduce the issue:
- Create a content type in the syndication hub, with one or more event receivers attached, and publish it
- Create a child content type in a subscribing site based on the content type created in the hub, and add one or more event receivers directly to it (at this point it should have the event receivers from the global content type as well as the new ones added in this step)
- Update the parent content type in the hub by adding one or more additional event receivers
- Republish the content type in the hub
- Once the sync takes place, the child content type no longer has the event receivers that were attached to it, and instead only reflects the event receivers in its parent (I have also found through other configurations where the parent event receivers never make it to the child content type)
Update: 10/31/2011
I have reported the issue to Microsoft, and they have been able to reproduce it, but at this time, I do not have any additional information.
The Fix
The one quick fix to this solution is to reattach any event receivers on your child content types that were removed. However, I am still researching this issue for more information. I will update this post once I have more details.
Cheers,
Matt
Posted by mjimison
on May 11, 2011
C#,
Event Receiver,
SharePoint /
No Comments
There comes a time in developing SharePoint solutions where you may find yourself asking:
This is not the time I want my event receiver to run
This is not the place where I can set EventFiringEnabled = false
This is not the way I want this call to SystemUpdate() to behave
You’ve probably developed an event receiver before that updated something, and you used EventFiringEnabled to keep the receiver from recursively calling itself (or its 2007 method equivalent). However, have you ever encountered a time where you were programmatically updating something in a Workflow, in PowerShell, etc… and you noticed that when calling SystemUpdate() your event receivers still fired, and this caused you an issue? The good news is that there is a way to get around this. It relies on utilizing EventFiringEnabled.
The summary of how EventFiringEnabled works is that it is a thread-specific setting that effects any items being updated. We just need to do 2 things:
- Create an event receiver that just has methods for disabling and enabling event firings (you don’t need to override a single method)
- Create some code where we instantiate a new instance of this event receiver, and execute your code in between calling your Disable and Enable methods on the event receiver instance
I like to take this a little further and create a delegate that I can pass into a utility function that allows me just to pass some code into a method, and I know that it gets executed without events firing. This is the same pattern that SPSecurity.RunWithElevatedPrivileges uses, and it’s helpful.
Here’s the code to help you make this happen:
Event Receiver Code
public class SPRunWithoutEventsFiringEventReceiver : SPItemEventReceiver
{
#region Methods
public void DisableEvents()
{
this.EventFiringEnabled = false;
}
public void EnableEvents()
{
this.EventFiringEnabled = true;
}
#endregion
}
Utility Method
public static class SPUtilities
{
public delegate void RunWithoutEventsFiringDelegate();
public static void RunWithoutEventsFiring(RunWithoutEventsFiringDelegate code)
{
SPRunWithoutEventsFiringEventReceiver eventReceiver = new SPRunWithoutEventsFiringEventReceiver();
try
{
eventReceiver.DisableEvents();
code();
}
finally
{
eventReceiver.EnableEvents();
}
}
}
Example Usage
SPUtilities.RunWithoutEventsFiring(delegate()
{
item["Title"] = "New Update";
item.SystemUpdate(false);
});
I hope that you found the article helpful, and that this comes in handy on one of your future projects!
Cheers,
Matt