Wednesday, October 22, 2008

Attach an event handler to a specific SharePoint list

When we attach an event handler through Features in SharePoint using “ListTypeId”, it attaches event handlers to all the lists of that particular type. This will result in a large performance hit. To execute the written code for a particular list we will have to check either with ListId or ContentTypeId.
So, here is a way of attaching an event handler to a specific list on “FeatureActivated” and to remove the event handler from the list on “FeatureDeactivating”. This is the best method I can find as of now for attaching and removeing the event handler to a specific SharePoint List.

const string assembly = "ListItemPermissions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5";
const string listReceiverName = "ListItemPermissions.ListItemPermissionsItemEventReceiver";
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
try
{
// get a reference to the current SPWeb
SPWeb _SPWeb = SPContext.Current.Web;
_SPWeb.AllowUnsafeUpdates = true;
// get a reference to the "Projects" list
SPList _projectsList = (SPList)_SPWeb.Lists["Projects"];

// if the "projectsList" list exists
if (_projectsList != null)
{
// create an empty Guid
Guid _ItemUpdatedGuid = Guid.Empty;
Guid _ItemAddedGuid = Guid.Empty;

// enumerate thru all of the event receiver definitions, attempting to
// locate the one we are adding
foreach (SPEventReceiverDefinition _SPEventReceiverDefinition in _projectsList.EventReceivers)
{
// if we find the event receiver we are about to add
// record its Guid
if (_SPEventReceiverDefinition.Type == SPEventReceiverType.ItemUpdated &&
_SPEventReceiverDefinition.Assembly == assembly &&
_SPEventReceiverDefinition.Class == listReceiverName)
{
_ItemUpdatedGuid = _SPEventReceiverDefinition.Id;
}

if (_SPEventReceiverDefinition.Type == SPEventReceiverType.ItemAdded &&
_SPEventReceiverDefinition.Assembly == assembly &&
_SPEventReceiverDefinition.Class == listReceiverName)
{
_ItemAddedGuid = _SPEventReceiverDefinition.Id;
}
}

// if we did not find the event receiver we are adding, add it
if (_ItemUpdatedGuid == Guid.Empty)
{
_projectsList.EventReceivers.Add(SPEventReceiverType.ItemUpdated, assembly, listReceiverName);
}
if (_ItemAddedGuid == Guid.Empty)
{
_projectsList.EventReceivers.Add(SPEventReceiverType.ItemAdded, assembly, listReceiverName);
}

_projectsList.Update();
_SPWeb.Update();
_SPWeb.AllowUnsafeUpdates = false;
}
}

catch (System.Exception ex)
{
PortalLog.LogString(ex.StackTrace);
throw new SPException(ex.Message);
}
}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
try
{
SPWeb _SPWeb = SPContext.Current.Web;
_SPWeb.AllowUnsafeUpdates = true;
// get a reference to the "Projects" list
SPList _projectsList = (SPList)_SPWeb.Lists["Projects"];
while(_projectsList.EventReceivers.Count > 0)
{
if (_projectsList.EventReceivers[_projectsList.EventReceivers.Count-1].Assembly.Equals(assembly))
{
_projectsList.EventReceivers[_projectsList.EventReceivers.Count-1].Delete();
}
} // looping thru event receivers.

_projectsList.Update();
_SPWeb.Update();
_SPWeb.AllowUnsafeUpdates = false;
}
catch (System.Exception ex)
{
PortalLog.LogString(ex.StackTrace);
throw new SPException(ex.Message);
}
}

1 comment:

  1. Your loop in FeatureDeactivating will be infinite if there are any other events registered on that list that do not come from that assembly.

    ReplyDelete