Question

I have an event receiver written by someone else. It originally came with events for ItemCheckingIn and ItemCheckedIn, but we needed something to handle simple metadata updates, too. Since those don't necessarily require checkout/checkin in a document library, I added ItemUpdated to the code (I went to the properties of the event receiver thing in the project and selected "true" for that method, which added the empty method to my code, and xml goodies to elements.xml). I then tested this out and it did not work. That is, ItemCheckingIn and ItemCheckedIn still did their thing, but ItemUpdated did not. I then added ItemUpdating and tried that - still no luck.

Is there some step I'm missing here? People say all kinds of things about stuff being registered but seriously isn't that supposed to be handled by all the feature settings and stuff? Can you only add these things when you are first creating the eventreceiver in visual studio? It's not like there's an error or even would be an error - I copied the code from one of the original methods - the event just does not even fire.

Any clues out there?

Thanks,

  • Matt

UPDATE **

After the answer below I got a bug up my rear and went back to my solution in Visual Studio, looking for more clues. It turns out that the "feature" has C# code related to my event reciever (FeatureName.EventReciever.cs). In there, the particular events being handled are assigned to a configurable content type (set in web.config) VIA CODE. Is this normal? Should I RTFM at this point and figure out how this stuff is really done? I thought the Elements.xml for the EventReceiver handled this...

Code for FeatureName.EventReceiver.cs:

    public override void FeatureActivated(SPFeatureReceiverProperties properties)
    {

        try
        {
            SPWeb web = properties.Feature.Parent as SPWeb;

            //di-associate CWTEventReceiver from CWT Print only content type
            DisableCWTEventReceiver(web);


            //associate CWTEventReceiver to content type as defined in configuration <activefields sharepointcontenttypename="CWT Print Only"> 
                FmiMetadataMappingHandler mappingHandler = WebConfigurationManager.OpenWebConfiguration("/", web.Site.WebApplication.Name).GetSection(Utils.GetConfigSectionNameForWeb(web)) as FmiMetadataMappingHandler;
                SPContentType ct = web.ContentTypes[mappingHandler.ActiveFields.SharepointContentTypeName];

                if (ct != null)
                {

                    Assembly assembly = Assembly.GetExecutingAssembly();
                    AssemblyName assName = assembly.GetName();
                   // bind event receiver to ItemCheckingIn Event                                      
                    SPEventReceiverDefinition receiverCheckingIn = ct.EventReceivers.Add();
                    receiverCheckingIn.Name = "CWTEventReceiverItemCheckingIn";
                    receiverCheckingIn.Type = SPEventReceiverType.ItemCheckingIn;
                    receiverCheckingIn.SequenceNumber = 1000;
                    receiverCheckingIn.Assembly = assName.FullName;
                    receiverCheckingIn.Class = EVENT_RECEIVER_CLASS_NAME;
                    receiverCheckingIn.Update();

                    // bind event receiver to ItemCheckedIn Event                                      
                    SPEventReceiverDefinition receiverCheckedIn = ct.EventReceivers.Add();
                    receiverCheckedIn.Name = "CWTEventReceiverItemCheckedIn";
                    receiverCheckedIn.Type = SPEventReceiverType.ItemCheckedIn;
                    receiverCheckedIn.SequenceNumber = 1001;
                    receiverCheckedIn.Assembly = assName.FullName;
                    receiverCheckedIn.Class = EVENT_RECEIVER_CLASS_NAME;
                    receiverCheckedIn.Update();
                    //update content type with event receiver
                    ct.Update(true);
                }

        }
        catch (Exception ex)
        {
            Utils.LogError(ex.Message, ex.StackTrace);
        }

    }
Was it helpful?

Solution

Event receivers are generally attached to lists by means of a list definition (which can define event receivers that are attached upon deployment) or programmatically through custom code. Depending on how you're deploying this event receiver, you might not actually be attaching the receiver to your list.

You can use PowerShell to see which event receivers are attached: http://social.msdn.microsoft.com/Forums/en-US/sharepointgeneralprevious/thread/4d006ad1-c055-4095-97b5-52e0f45f6c0f

If the code in that link reveals that the receiver's not attached, you can also use PowerShell to attach an event receiver: http://sharepintblog.com/2011/06/04/adding-event-receivers-with-powershell/

Hope this helps!

* Edit by Matt *

Please see the comments below for a fleshing-out of why this is the answer.

OTHER TIPS

Your problem seems to be largely getting troubleshooted (troubleshot?) in the other answer's discussion thread, but to answer the specific question you're asking, there are several ways you can register/unregister event receivers:

  1. Elements.xml (or inline Elements in your Feature.xml as you prefer)
  2. PowerShell
  3. FeatureReceiver code (which is, in and of itself, an event receiver)
  4. A custom solution (SP2007 example: http://spscustomadmin.codeplex.com/ )

How you do it largely depends on your approach to the solution. In other words, if you're developing a code-heavy solution, you'll probably want to do your event receiver registrations in code too, as it gives you the most flexibility and tools for diagnosis for problems such as what you're dealing with above. As an example of something I work with a lot:

Your problem seems to be largely getting troubleshooted (troubleshot?) in the other answer's discussion thread, but to answer the specific question you're asking, there are several ways you can register/unregister event receivers:
  1. Elements.xml (or inline Elements in your Feature.xml as you prefer)
  2. PowerShell
  3. FeatureReceiver code (which is, in and of itself, an event receiver)
  4. A custom solution (SP2007 example: http://spscustomadmin.codeplex.com/ )

How you do it largely depends on your approach to the solution. In other words, if you're developing a code-heavy solution, you'll probably want to do your event receiver registrations in code too, as it gives you the most flexibility and tools for diagnosis for problems such as what you're dealing with above. As an example of something I work with a lot:

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

using Microsoft.Office.Server.Diagnostics;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace MyCompany.Tools
{
    public class FeatureReceiver : SPFeatureReceiver
    {
        private String _executingAssembly
        {
            get { return Assembly.GetExecutingAssembly().FullName; }
        }

        String eventAssembly = "MyCompany.Tools.Tool, Version=1.0.0.0, Culture=neutral, PublicKeyToken=35049b4e811be271";
        String eventClass = "MyCompany.Tools.Tool.EventReceiver";
        String targetList = "Receiver List";

        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            String featureProperties = String.Format("{0} ({1})", properties.Feature.Definition.DisplayName, properties.Feature.Definition.Id.ToString());
            String activationProperties = GetScopeAndParent(properties.Definition.Scope, properties.Feature.Parent);
            LogInformation(String.Concat("Feature Activated: ", featureProperties));
            LogInformation(activationProperties);

            try
            {
                using (SPWeb web = (SPWeb)properties.Feature.Parent)
                {
                    SPList list = web.Lists[targetList];

                    list.EventReceivers.Add(SPEventReceiverType.ItemAdded, eventAssembly, eventClass);
                    LogInformation(String.Format("Added {0} receiver to list {1} successfully.", SPEventReceiverType.ItemAdded.ToString(), list.Title));
                }
            }
            catch (Exception ex)
            {
                LogCritical(ex, String.Format("Exception encountered in {0}:", _executingAssembly));
            }
        }

        public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        {
            String featureProperties = String.Empty;
            if (properties.Feature != null)
            {
                featureProperties = String.Format("{0} ({1})", properties.Feature.Definition.DisplayName, properties.Feature.Definition.Id.ToString());
            }
            else
            {
                featureProperties = String.Format("{0} ({1})", properties.Definition.DisplayName, properties.Definition.Id.ToString());
            }
            LogInformation(String.Concat("Feature Installed: ", featureProperties));
            if (properties.Feature != null)
            {
                LogInformation(String.Concat((properties.Feature.Parent.ToString())));
            }
        }

        public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        {
            String featureProperties = String.Empty;
            if (properties.Feature != null)
            {
                featureProperties = String.Format("{0} ({1})", properties.Feature.Definition.DisplayName, properties.Feature.Definition.Id.ToString());
            }
            else
            {
                featureProperties = String.Format("{0} ({1})", properties.Definition.DisplayName, properties.Definition.Id.ToString());
            }
            LogInformation(String.Concat("Feature Uninstalling: ", featureProperties));
            if (properties.Feature != null)
            {
                LogInformation(String.Concat((properties.Feature.Parent.ToString())));
            }
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            String featureProperties = String.Format("{0} ({1})", properties.Feature.Definition.DisplayName, properties.Feature.Definition.Id.ToString());
            String activationProperties = GetScopeAndParent(properties.Definition.Scope, properties.Feature.Parent);
            LogInformation(String.Concat("Feature Deactivating: ", featureProperties));
            LogInformation(activationProperties);

            using (SPWeb web = properties.Feature.Parent as SPWeb)
            {
                SPList list = null;
                try
                {
                    list = web.Lists[targetList];

                    for (int i = (list.EventReceivers.Count - 1); i >= 0; i--)
                    {
                        if (list.EventReceivers[i].Assembly == eventAssembly)
                        {
                            list.EventReceivers[i].Delete();
                        }
                    }
                }
                catch { } //If the list doesn't exist, then the event receiver is gone too, so just deactivate the feature.
            }
        }

        private String GetScopeAndParent(SPFeatureScope scope, Object parent)
        {
            String returnValue = String.Empty;

            try
            {
                if (scope == SPFeatureScope.Farm)
                {
                    SPFarm farm = (SPFarm)parent;
                    returnValue = String.Format("  Farm: {0} ({1})", farm.Name, farm.Id.ToString());
                }
                else if (scope == SPFeatureScope.WebApplication)
                {
                    SPWebApplication webApp = (SPWebApplication)parent;
                    returnValue = String.Format("  Web Application: {0} ({1})", webApp.Name, webApp.Id.ToString());
                }
                else if (scope == SPFeatureScope.Site)
                {
                    using (SPSite site = (SPSite)parent)
                    {
                        returnValue = String.Format("  Site: {0} ({1})", site.Url, site.ID.ToString());
                    }
                }
                else if (scope == SPFeatureScope.Web)
                {
                    using (SPWeb web = (SPWeb)parent)
                    {
                        returnValue = String.Format("  Web: {0} ({1})", web.Url, web.ID.ToString());
                    }
                }
            }
            catch { }

            return returnValue;
        }

        private void LogInformation(String message)
        {
            Trace.WriteLine(message);
            PortalLog.DebugLogString(PortalLogLevel.Information, message);
        }

        private void LogUnexpected(String message)
        {
            Trace.WriteLine(message);
            PortalLog.DebugLogString(PortalLogLevel.Unexpected, message);
        }

        private void LogCritical(Exception ex, String message)
        {
            Trace.WriteLine(message);
            Trace.WriteLine(ex.Message);
            Trace.WriteLine(ex.StackTrace);

            PortalLog.DebugLogString(PortalLogLevel.Critical, message);
            PortalLog.DebugLogString(PortalLogLevel.Critical, ex.Message);
            PortalLog.DebugLogString(PortalLogLevel.Critical, ex.StackTrace);
        }
    }
}

It doesn't implement FeatureUpdating(), PortalLog is deprecated now, and it's probably not the most efficient way, but it works well enough and you can tailor it as needed.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top