locked
EventReceivers firing on all custom lists RRS feed

  • Question

  • Hi everyone, I've come here as a last resort before I find a revolver and a barn. I've struggled with this problem for weeks, even though it should in theory be a ridiciously simple thing.

    My problem is that I have build a eventreceiver in VS2010 which for some reason is triggered on more lists than I specify. When I modifiy a list, the itemadding/added/updated/deleted-event is triggered for all the lists in the site. I don't have a clue why this happens, and I will provide code below. I have looked into the possibility that older versions/eventreceivers have been in action, hence I've deactivated all solutions and all, but a couple of integrated features. I've also started a new project in VS several times, and copied only the code over to the new project.

    Obviously I've removed the ListTemplateId from the Receivers in the Elements.xml file. I should mention though, that my eventreceivers were still called even if I didn't assign them to any list in elements.xml, or if I specified ListUrl="myList" for example. The result is that the itemadding/added/updated/deleted-event is triggered for all the lists in the site.

    My elements.xml file is as below:

    <?xml version="1.0" encoding="utf-8"?>
    
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    
     <Receivers>
    
      <Receiver>
    
      <Name>CustomerHandlerItemAdding</Name>
    
      <Type>ItemAdding</Type>
    
      <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
    
      <Class>IntranetEventReceivers.CustomerHandler.CustomerHandler</Class>
    
      <SequenceNumber>10000</SequenceNumber>
    
      </Receiver>
    
      <Receiver>
    
      <Name>CustomerHandlerItemAdded</Name>
    
      <Type>ItemAdded</Type>
    
      <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
    
      <Class>IntranetEventReceivers.CustomerHandler.CustomerHandler</Class>
    
      <SequenceNumber>10000</SequenceNumber>
    
      </Receiver>
    
      <Receiver>
    
      <Name>CustomerHandlerItemUpdated</Name>
    
      <Type>ItemUpdated</Type>
    
      <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
    
      <Class>IntranetEventReceivers.CustomerHandler.CustomerHandler</Class>
    
      <SequenceNumber>10000</SequenceNumber>
    
      </Receiver>
    
      <Receiver>
    
      <Name>CustomerHandlerItemDeleted</Name>
    
      <Type>ItemDeleted</Type>
    
      <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
    
      <Class>IntranetEventReceivers.CustomerHandler.CustomerHandler</Class>
    
      <SequenceNumber>10000</SequenceNumber>
    
      </Receiver>
    
    
    
     </Receivers>
    
    </Elements>
    
    
    
    

     My EventReceiver-class is like the following code. The LogWriter.WriteToFile() method loggs to a textfile and needless to say, always logs that a item is added to a custom list as if the eventreceiver is attached to that list.

    using System;
    
    using System.Security.Permissions;
    
    using Microsoft.SharePoint;
    
    using Microsoft.SharePoint.Security;
    
    using Microsoft.SharePoint.Utilities;
    
    using Microsoft.SharePoint.Workflow;
    
    using System.Web;
    
    using IntranetEventReceivers.Logic;
    
    using IntranetEventReceivers.Model;
    
    
    
    namespace IntranetEventReceivers.CustomerHandler
    
    {
    
     /// <summary>
    
     /// List Item Events
    
     /// </summary>
    
     public class CustomerHandler : SPItemEventReceiver
    
     {
    
      public CustomerHandler()
    
      {
    
       //It is not possible to write to file here. Will get "Activation Feature" error when trying to deploy!
    
      }
    
      /// <summary>
    
      /// An item is being added.
    
      /// </summary>
    
      public override void ItemAdding(SPItemEventProperties properties)
    
      {
    
       LogWriter.WriteToFile("\n Customerhandler started debugging ItemAdding, " + DateTime.Now.TimeOfDay + "\r", true, false);
    
       LogWriter.WriteToFile("\n Trying to add \"" + properties.AfterProperties[IntranetCustomerFields.Navn] + "\" to the list " + properties.List);
    
    
    
       if (properties.List.Title != IntranetLists.CustomerListe
    
        && properties.List.Title != IntranetLists.TilbudListe
    
        && properties.List.Title != IntranetLists.ProsjektListe) return;
    
    
    
       try
    
       {
    
        SPSecurity.RunWithElevatedPrivileges(delegate
    
        {
    
         base.EventFiringEnabled = false;
    
         base.ItemAdding(properties);
    
    
    
         var newIntranetSite = IntranetSite.GetIntranetSiteInstance(properties);
    
         NewMethods.CreateSite(newIntranetSite, properties.AfterProperties);
    
    
    
         //update the item that kicked off the workflow with the correct link
    
         properties.AfterProperties[IntranetCustomerFields.Link] = newIntranetSite.FullAbsPath + ", " + newIntranetSite.Name;
    
        });
    
       }
    
       catch (Exception ex)
    
       {
    
        LogWriter.WriteErrorToFile(ex, "ItemAdding");
    
        properties.ErrorMessage = ex.Message;
    
        properties.Cancel = true;
    
       }
    
       finally
    
       {
    
        base.EventFiringEnabled = true;
    
       }
    
      }
    
      /// <summary>
    
      /// An item was added
    
      /// </summary>
    
      /// <param name="properties"></param>
    
      public override void ItemAdded(SPItemEventProperties properties)
    
      {
    
       LogWriter.WriteToFile("\n CustomerHandler started debugging ItemAdded, " + DateTime.Now.TimeOfDay + "\r", true, false);
    
       LogWriter.WriteToFile("\n Tried to add \"" + properties.AfterProperties[IntranetCustomerFields.Navn] + "\" to the list " + properties.List);
    
    
    
       if (properties.List.Title != IntranetLists.CustomerListe
    
        && properties.List.Title != IntranetLists.TilbudListe
    
        && properties.List.Title != IntranetLists.ProsjektListe) return;
    
    
    
       try
    
       {
    
        base.EventFiringEnabled = false;
    
        base.ItemAdded(properties);
    
        SPSecurity.RunWithElevatedPrivileges(delegate
    
        {
    
         //Do asynchroneous stuff like adding to taxonomy
    
        });
    
       }
    
       catch (Exception ex)
    
       {
    
        LogWriter.WriteErrorToFile(ex, "ItemAdded");
    
        properties.ErrorMessage = ex.Message;
    
        properties.Cancel = true;
    
       }
    
       finally
    
       {
    
        base.EventFiringEnabled = true;
    
       }
    
      }
    
    
    
      /// <summary>
    
      /// An item was updated.
    
      /// </summary>
    
      public override void ItemUpdated(SPItemEventProperties properties)
    
      {
    
       LogWriter.WriteToFile("\n CustomerHandler started debugging ItemUpdated, " + DateTime.Now.TimeOfDay + "\r", true, false);
    
       LogWriter.WriteToFile("\n Tried to update \"" + properties.AfterProperties[IntranetCustomerFields.Navn] + "\" in the list " + properties.List);
    
    
    
       if (properties.List.Title != IntranetLists.CustomerListe
    
        && properties.List.Title != IntranetLists.TilbudListe
    
        && properties.List.Title != IntranetLists.ProsjektListe
    
        && properties.List.Title != IntranetLists.InfoListe) return;
    
    
    
       try
    
       {
    
        SPSecurity.RunWithElevatedPrivileges
    
          (delegate
    
          {
    
           base.EventFiringEnabled = false;
    
           base.ItemUpdating(properties);
    
    
    
           const string tmpRelPath = "/" + IntranetSettings.SubDirectoryName;
    
           SPList list = properties.List;
    
           SPListItem item = properties.ListItem;
    
           string sourceSiteUrl = properties.WebUrl;
    
           string sourcePath = sourceSiteUrl.Substring(sourceSiteUrl.IndexOf(tmpRelPath) + tmpRelPath.Length);
    
           if (sourcePath.StartsWith("/")) sourcePath = sourcePath.Substring(1);
    
           var sourceType = (string)properties.Web.GetProperty(IntranetKeys.KeyDefinition);
    
    
    
           //Creates a cibgerInfo-object to store information about the source and target-lists, as well as keeping track of URLs
    
           var changedIntranetInfo = new IntranetInfo(item.Title, list.Title, sourceType, sourcePath);
    
    
    
           //Update the mirrored list with the modified information.
    
           UpdateMethods.UpdateMirrorList(changedIntranetInfo, item);
    
    
    
           LogWriter.WriteToFile(changedIntranetInfo.ToString());
    
          });
    
       }
    
       catch (Exception ex)
    
       {
    
        LogWriter.WriteErrorToFile(ex, "ItemUpdated");
    
        properties.ErrorMessage = ex.Message;
    
        properties.Cancel = true;
    
       }
    
       finally
    
       {
    
        base.EventFiringEnabled = true;
    
       }
    
      }
    
    
    
      /// <summary>
    
      /// An item is being deleted.
    
      /// </summary>
    
      public override void ItemDeleting(SPItemEventProperties properties)
    
      {
    
       LogWriter.WriteToFile("\n Started debugging ItemDeleting, " + DateTime.Now.TimeOfDay + "\r", true, false);
    
       LogWriter.WriteToFile("\n Tried to delete \"" + properties.AfterProperties[IntranetCustomerFields.Navn] + "\" in the list " + properties.List);
    
       if (properties.List.Title != IntranetLists.CustomerListe
    
         && properties.List.Title != IntranetLists.TilbudListe
    
         && properties.List.Title != IntranetLists.ProsjektListe
    
        && properties.List.Title != IntranetLists.InfoListe) return;
    
       try
    
       {
    
        if (properties.List.Title == IntranetLists.InfoListe)
    
        {
    
         properties.Status = SPEventReceiverStatus.CancelNoError;
    
         properties.Cancel = true;
    
        }
    
        base.EventFiringEnabled = false;
    
        base.ItemDeleting(properties);
    
    
    
        LogWriter.WriteToFile("\n Deleting " + properties.ListItem.Title);
    
       }
    
       catch (Exception ex)
    
       {
    
        LogWriter.WriteErrorToFile(ex, "ItemDeleting");
    
        properties.ErrorMessage = ex.Message;
    
        properties.Cancel = true;
    
       }
    
       finally
    
       {
    
        base.EventFiringEnabled = true;
    
       }
    
      }
    
     }
    
    }<br/><br/>
    
    
    
    

    I also have a FeatureActivated method which adds the eventreceiver to the list:

     

    public override void FeatureActivated(SPFeatureReceiverProperties properties)
    
      {
    
       SPWeb site = properties.Feature.Parent as SPWeb;
    
       SPList CustomerList = site.Lists["Customer"];
    
       string itemReceiverName = "IntranetEventReceivers.CustomerHandler.CustomerHandler";
    
       string asmName = "IntranetEventReceivers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=15ef7f7b92643fbd";
    
       
    
       CustomerList.EventReceivers.Add(SPEventReceiverType.ItemAdding, asmName, itemReceiverName);
    
       CustomerList.EventReceivers.Add(SPEventReceiverType.ItemAdded, asmName, itemReceiverName); 
    
       CustomerList.EventReceivers.Add(SPEventReceiverType.ItemUpdated, asmName, itemReceiverName);
    
       CustomerList.EventReceivers.Add(SPEventReceiverType.ItemDeleted, asmName, itemReceiverName); 
    
      }<br/>}<br/>
    
    

     

    I think the problem lies in the settings or the xml-file, because the code is run regardless so in theory it shouldn't matter what logic it does (that's also why I don't explain the large code segment in detail).

     

    Anyone seen something similiar? I'd be thrilled if someone could help me with this.

    Thanks,

    Tarjei

     

    • Moved by Anjali Ch -MSFT Wednesday, November 10, 2010 5:35 PM Moving to Programming (From:SharePoint 2010 - General Questions and Answers)
    • Edited by tarjeieo Tuesday, December 7, 2010 2:09 PM fixed weird names
    Sunday, October 24, 2010 4:48 PM

Answers

  • Not sure if you have found the resolution to this, but here's what is happening in your scenario...

    If the ListTemplateId attribute is not present in the elements.xml file, the provisioning process provisions the event receiver on all the lists.  And since, you are specifically provisioning the event handler again on a specific list through FeatureActivating event, there are 2 instances of the same event handler associated with "Kunde" list.

    Option1: You need to either remove the elements.xml file completely and just provision the feature (and let the featureactivating event do the job of associating the event receiver to a specific list).  Option2: Or, you can simply deploy the event receiver assembly to GAC in the deployment process and associate it to a particular list using a separate console/winform application.  However, the first option mentioned above should be good enough for your scenario.

    Let us know if this helps!

    -Sridhar


    These postings are provided "AS IS" with no warranties, and confers no rights.
    • Proposed as answer by Anjali Ch -MSFT Monday, November 22, 2010 3:19 PM
    • Marked as answer by Lily Wu Tuesday, November 23, 2010 2:02 AM
    Monday, November 15, 2010 1:40 PM

All replies

  • Hi,

    i think it is a problem with your previous deployments because an event receiver once registered stays registered as long as you don't remove the event receiver manually. What i do when i write a event receiver i register in the feature activation and unregister it in the deactivation. Works best because then i'm sure that the event receiver only will be registered once.

    If your list was "custom list" template id then you have the event handler might anywhere. What you can do is try to explore the registered event receiver. You can use http://mossytips.blogspot.com/2008/08/event-handler-explorer-tool.html. It is written for 2007 but works quite well with 2010 because nothing has changed in this topic.

    Please check the content types like Item content type if they have event receiver registered. What you can do is create a new site collection deploy your solution and check if the event receiver will be fired in the same way than before. I can't see any failure in your code how you registering your event receiver.

    Regards Stefan


    http://www.n8d.at/blog
    MCTS - SharePoint / WSS Configuration and Development
    Sunday, October 24, 2010 5:42 PM
  • Bind the event receiver using code instead of using the Elements XML.  See this discussion:
    http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/14c75539-9e96-434b-a26c-79ad4aa28e79

    Here's a simple example: http://blah.winsmarts.com/2006-7-Sharepoint_2007__List_Events_Practical_Example__Creating_a_rigged_survey.aspx

    You can also attach the event receiver to a Content Type and then associate that to your custom list.

     


    Mike Smith TechTrainingNotes.blogspot.com
    Sunday, October 24, 2010 7:15 PM
  • Hi Stefan, thanks for looking at this.

    I have done quite a bit of debugging of my lists. I have used SharePointManager 2010 to explore the object model tree, and what I find is that the "Kunde" list correctly has my eventreceivers connected to it. The other lists does not have any event receivers connected. I have also used PowerShell and output to explore the lists, and the results are the same.

    Also, I am doing what you are recommending (adding and removing eventreceivers in the featureeventreceivers activated and deactivated.).

    I have also tried my code in several site collections(even farms), and the results are the same.

    I can't for the life of me figure out what is wrong.

    I will post some new outputinformation in a following post.

    Sunday, October 24, 2010 8:48 PM
  • Hi Mike, thanks for looking at this.

    As you can see from my code, I am not binding my eventreceivers through Elements XML, even though I've tried that as well, as noted in my OP.

     

    Sunday, October 24, 2010 8:49 PM
  • I have done some more debugging to see what kind of eventreceiver the lists are connected to. The results are, although not shocking, quite scary.

    First, here is the start of my ItemAdding-method, which prints out info about the invoked List:

    public override void ItemAdding(SPItemEventProperties properties)
     {
      StringBuilder sb = new StringBuilder();
      sb.Append("\nCustomerhandler started debugging ItemAdding, " + DateTime.Now.TimeOfDay);
      sb.Append("\r\n Trying to add \"" + properties.AfterProperties[IntranetCustomerFields.Navn] + "\" to the list " + properties.List);
      sb.Append("\r\n The list has the following eventreceivers attatched: ");
      foreach (SPEventReceiverDefinition edc in properties.List.EventReceivers)
      {
      sb.Append("\r\n \t class: " + edc.Class);
      }
      LogWriter.WriteToFile(sb.ToString());
    //rest of code
    }
    

     

    I first tried to add an item "Statoil" to a new list "LOL" which is not done anything with in any way. Thereafter I tried to add "Statoil" to the correct list "Customer" (where the logic is supposed to happen).

    This codesnippet provides the following output:

     

    2010-10-24 22:59:28, [DEBUG] 
    Customerhandler started debugging ItemAdding, 22:59:28.2683091
    Trying to add "Hydro" to the list LOL
    The list has the following eventreceivers attatched:
    2010-10-24 22:59:28, [DEBUG]
    CustomerHandler started debugging ItemAdded, 22:59:28.2823100

    2010-10-24 22:59:28, [DEBUG]
    Tried to add "Hydro" to the list LOL
    2010-10-24 22:59:36, [DEBUG]
    Customerhandler started debugging ItemAdding, 22:59:36.9618064
    Trying to add "Hydro" to the list Customer
    The list has the following eventreceivers attatched:
    class: IntranetEventReceivers.CustomerHandler.CustomerHandler type: ItemAdding
    class: Microsoft.SharePoint.Workflow.SPWorkflowAutostartEventReceiver type: ItemAdded
    class: IntranetEventReceivers.CustomerHandler.CustomerHandler type: ItemAdded
    class: Microsoft.SharePoint.Workflow.SPWorkflowAutostartEventReceiver type: ItemUpdated
    class: IntranetEventReceivers.CustomerHandler.CustomerHandler type: ItemUpdated
    class: IntranetEventReceivers.CustomerHandler.CustomerHandler type: ItemDeleted

    2010-10-24 22:59:39, [DEBUG]
    Trying to add "Hydro" to the list Customer
    2010-10-24 22:59:39, [DEBUG]
    Customerhandler started debugging ItemAdding, 22:59:39.9989801
    Trying to add "Hydro" to the list Customer
    The list has the following eventreceivers attatched:
    class: IntranetEventReceivers.CustomerHandler.CustomerHandler type: ItemAdding
    class: Microsoft.SharePoint.Workflow.SPWorkflowAutostartEventReceiver type: ItemAdded
    class: IntranetEventReceivers.CustomerHandler.CustomerHandler type: ItemAdded
    class: Microsoft.SharePoint.Workflow.SPWorkflowAutostartEventReceiver type: ItemUpdated
    class: IntranetEventReceivers.CustomerHandler.CustomerHandler type: ItemUpdated
    class: IntranetEventReceivers.CustomerHandler.CustomerHandler type: ItemDeleted
    2010-10-24 22:59:42, [DEBUG]
    CustomerHandler started debugging ItemAdded, 22:59:42.0270961

    2010-10-24 22:59:42, [DEBUG]
    Tried to add "Hydro" to the list Customer
    2010-10-24 22:59:42, [DEBUG]
    CustomerHandler started debugging ItemAdded, 22:59:42.0330965

    2010-10-24 22:59:42, [DEBUG]
    Tried to add "Hydro" to the list Customer



    Also note that the method(s) are called two times for some reason.

    Does this make sense to anyone?

    • Edited by tarjeieo Tuesday, December 7, 2010 2:10 PM fixed weird names
    Sunday, October 24, 2010 8:56 PM
  • Hi,

    jeah sure make sense i have not taken a closer look on your Event receivers. This is because you have to much event receivers attached i think. So basically there is a differnence between the item receiver.

    ItemAdding and ItemUpdating those are synchronous event receiver therefore they will be fired right after the user have clicked the save button. ItemAdded and ItemUpdated are asynchronous events. So the get fired a time after ItemAdding and ItemUpdating has happend. You need to decide when you want to do all, if you want to do it asynchronous or synchronous i won't mix those different types.

    So are your lists connected using lookup in your site ? This could might cause the firing of your event receiver to.

    Regards Stefan.


    http://www.n8d.at/blog
    MCTS - SharePoint / WSS Configuration and Development
    Sunday, October 24, 2010 9:26 PM
  • Stefan;

    I don't see a problem with mixing ItemAdding and ItemAdded, after all they are triggered in different steps of the item add-process. Besides, this is the normal way to do it, isn't it?

    No, these lists are not connected using lookup.

    Monday, October 25, 2010 7:20 AM
  • *Shameless bump*
    Wednesday, October 27, 2010 6:22 AM
  • Not sure if you have found the resolution to this, but here's what is happening in your scenario...

    If the ListTemplateId attribute is not present in the elements.xml file, the provisioning process provisions the event receiver on all the lists.  And since, you are specifically provisioning the event handler again on a specific list through FeatureActivating event, there are 2 instances of the same event handler associated with "Kunde" list.

    Option1: You need to either remove the elements.xml file completely and just provision the feature (and let the featureactivating event do the job of associating the event receiver to a specific list).  Option2: Or, you can simply deploy the event receiver assembly to GAC in the deployment process and associate it to a particular list using a separate console/winform application.  However, the first option mentioned above should be good enough for your scenario.

    Let us know if this helps!

    -Sridhar


    These postings are provided "AS IS" with no warranties, and confers no rights.
    • Proposed as answer by Anjali Ch -MSFT Monday, November 22, 2010 3:19 PM
    • Marked as answer by Lily Wu Tuesday, November 23, 2010 2:02 AM
    Monday, November 15, 2010 1:40 PM
  • I just saw your post - I never thought of deleting the elements.xml file completely - I didn't know that was even possible!

    Will try it this week, I'll let you know. Thanks.

     

    -Tarjei

    Tuesday, November 30, 2010 12:25 PM
  • Just tested this, and it looks like this is the key! Thanks alot! :D
    Monday, December 6, 2010 5:56 PM
  • Sridhar,

    Thank you so much! I had the same problem, where I was assigning the Event Receiver in code, but there were duplicate Event Receivers showing up in other lists.  I was just using an example for the elements.xml file, which included a Receivers tag for the ListTemplateID of 100.  I removed the Receivers tag from each elements.xml file and now the lists only have the Event Receivers they should.

     

     


    Christopher W. Douglas
    Friday, January 21, 2011 6:52 PM