carruw
carruw

Reputation: 359

How to attach Event Receiver to SPList programmatically?

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.

Upvotes: 4

Views: 16421

Answers (3)

Luis
Luis

Reputation: 6001

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);

Upvotes: 8

Eugene Rosenfeld
Eugene Rosenfeld

Reputation: 780

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.

Upvotes: 2

naivists
naivists

Reputation: 33491

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);

Upvotes: 2

Related Questions