How to attach Event Receiver to SPList programmatically?

16.3k views Asked by At

I'm working on a project i SharePoint 2010 where I have several under sites. each under site contain a list with news and I want to attach an Event Receiver to those lists.

The under sites and lists are created programmatically but I cannot attach the Event Receiver I have in my VS2010 Solution.

I've tried with this:

SPList list = new SPSite(siteURL).OpenWeb().Lists[listName]; 
SPEventReceiverDefinitionCollection eventReceivers = list.EventReceivers;

SPEventReceiverDefinition eventReceiver = eventReceivers.Add();
eventReceiver.Name = receiverName;
eventReceiver.Synchronization = SPEventReceiverSynchronization.Synchronous; 
eventReceiver.Type = SPEventReceiverType.ItemAdded;
eventReceiver.SequenceNumber = sequenceNumber; 
eventReceiver.Assembly = assemblyFullName;
eventReceiver.Class = assemblyClassName;
eventReceiver.Data = receiverData;

eventReceiver.Update();

But it does not work.

The error message is "Could not load file or assembly 'Projekt_Test1\, \, Version\=1.0.1777.23493\, Culture\=neutral\, PublicKeyToken\=49c7547d535382ab' or one of its dependencies. The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)"

Thanks for help.

3

There are 3 answers

0
naivists On

I have never succeeded with this version of eventReceivers.Add() you are using.

Here is a powershell framgent I'm using, it would be very similar in C#

$ev = $currentList.EventReceivers.Add([Microsoft.SharePoint.SPEventReceiverType]::ItemAdded, $assemblyName, $className);
0
Eugene Rosenfeld On

Couple of things to look at:

  1. Your assembly version is listed as 1.0.1777.23493. That looks like it is being auto-incremented. You will want to set a fixed assembly version or it will update with every build, breaking your code.
  2. You're setting eventReceiver.Synchronization = SPEventReceiverSynchronization.Synchronous, but the ItemAdded is an asynchronous event.
  3. Make sure that your event receiver assembly has been deployed to the GAC on the SharePoint server, and that you have recycled the SharePoint application pools in IIS before you run your code.
0
Luis On

I end up creating a List Extension method for this:

public static void EnsureEventReceiver(this SPList list,IEnumerable<SPEventReceiverType> receiverTypes, Type eventHander, SPEventReceiverSynchronization synchronization, int sequenceNumber)
{
   foreach (SPEventReceiverType spEventReceiverType in receiverTypes)
   {
      string name = list.Title + spEventReceiverType.ToString();

      if (list.EventReceivers.Cast<SPEventReceiverDefinition>().All(i => i.Name != name))
      {
          SPEventReceiverDefinition eventReceiver = list.EventReceivers.Add();
          eventReceiver.Name = name;
          eventReceiver.Type = spEventReceiverType;
          eventReceiver.Assembly = eventHander.Assembly.FullName;
          eventReceiver.Class = eventHander.FullName;
          eventReceiver.SequenceNumber = sequenceNumber;
          eventReceiver.Synchronization = synchronization;
          eventReceiver.Update();
      }
   }    
}

Caveats, Limitations of this method:

  • Only one event per List, since this is good enough for me, if you need more then you need to pass the name as a parameter
  • Event handler methods are in the same class

You can use it like this:

list.EnsureEventReceiver(
     new[] { SPEventReceiverType.ItemAdded, SPEventReceiverType.ItemUpdated },
     typeof(NewsItemsHandler),
     SPEventReceiverSynchronization.Synchronous, 
     10000);