Sunday, April 17, 2011

Deploying Item Event Receiver (SPItemEventReceiver) in two approaches Feature Receiver and only feature (thru elements.xml)

While creating Event handlers/receivers, we have the option of creating the same in two different approaches. We can create event handlers to be associated with one particular list or all lists available with the same template type. Thus there could be two ways of implementing the receivers, though it all depends on the requirements.

In recent time I have created Item Event Receivers in both the ways, analyzed and have some findings to share, not sure whether this helps others. To see how to create Item Event Receivers visit my blog on How to create Item Event Receiver (SPItemEventReceiver)
Process 1(Generic with no Feature receivers)

We can find the template type in Elements.xml. See below the Receiver will get associated with all lists which has TemplateID as 100.

<?xml version="1.0" encoding="utf-8" ?>

<Elements xmlns=http://schemas.microsoft.com/sharepoint/>

<Receivers ListTemplateId="100">

In this process we only need the below files

  1. Feature.xml
  2. Elements.xml
  3. Event Handler class (event handler class inhering from SPItemEventReceiver)

 

  1. Feature.xml

The feature file will remain very simple, only with the basic details.

<?xml version="1.0" encoding="utf-8"?>

<Feature Id="62B66824-3AE2-4320-9949-6B59ED862C64"
Title="TestEventHandler"

Description="Adding/updating/deleting of any item in list"

Version="1.0.0.0"

Hidden="FALSE"

Scope="Web"

DefaultResourceFile="core"

ImageUrl ="NEWSPG.GIF"

xmlns="http://schemas.microsoft.com/sharepoint/">

<ElementManifests>

<ElementManifest Location="elements.xml"/>

</ElementManifests>

</Feature>
The feature will be very simple and straight forward, nothing special about this except mentioning the element manifest.

  1. Elements.xml

The elements.xml will hold all the receiver information.

<?xml version="1.0" encoding="utf-8" ?>

<Elements xmlns=http://schemas.microsoft.com/sharepoint/>

<Receivers ListTemplateId="100">

<Receiver> <Name>AddingEventHandler</Name>

<Type>ItemAdded</Type>

<SequenceNumber>10000</SequenceNumber>

<Assembly>TestEventHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ab011vdd6a7bfaba2</Assembly>
<Class>TestEventHandler.TestEventHandler</Class>
<Data></Data>
<Filter></Filter>
</Receiver>
<Receiver>
<Name>UpdatedEventHandler</Name>

<Type>ItemUpdated</Type>

<SequenceNumber>10000</SequenceNumber>

<Assembly>TestEventHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ab011vdd6a7bfaba2</Assembly>
<Class>TestEventHandler.TestEventHandler</Class>
<Data></Data>
<Filter></Filter>
</Receiver>
<Receiver>
<Name> Delete</Name>
<Type>ItemDeleting</Type>
<SequenceNumber>10000</SequenceNumber>
<Assembly>TestEventHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ab011vdd6a7bfaba2</Assembly>
<Class>TestEventHandler.TestEventHandler</Class>
<Data></Data>
<Filter></Filter>
</Receiver>
</Receivers>
</Elements>
Here on any item added/updated and deleting the event will fire and the class <Class>TestEventHandler.TestEventHandler</Class> would handle the events.

  1. Event Handler Class

Event handler class would inherit the base class and contain the custom code under.....

public class TestEventHandler: SPItemEventReceiver

public override void ItemAdded(SPItemEventProperties properties)

public override void ItemUpdated(SPItemEventProperties properties)

Process 2 (Feature receivers with target list)

If any Receiver is targeted for any particular list then it is always advisable to deploy the solution explicitly with the feature receiver and add to the Specific List's receiver collection. This will have two major advantages.

  1. The event handler will only get attached to the particular list on feature activation and would be removed on feature deactivation. (as compared to Process 1 approach, on feature deactivation the event receiver will still remain associated with the list)
  2. We can target the specific list to associate the

In this process we only need the below files

  1. Feature.xml
  2. FeatureReceiver
  3. Event Handler class (event handler class inhering from SPItemEventReceiver)

 

  1. Feature.xml

<?xml version="1.0" encoding="utf-8"?>

<Feature Id="62B66824-3AE2-4320-9949-6B59ED862C64"
Title="TestEventHandler"
Description="Adding/updating/deleting of any item in list"
Version="1.0.0.0"
Hidden="FALSE"
Scope="Web"
DefaultResourceFile="core"
ImageUrl ="NEWSPG.GIF"

ReceiverAssembly="TestEventHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ab011vdd6a7bfaba2"
ReceiverClass = "TestEventHandler.TestEventHandler"
xmlns=http://schemas.microsoft.com/sharepoint/>
</Feature>

Adding the Assembly and the feature receiver class information.

  1. Feature Receiver Class

This class would add the event handler class TestEventHandler to the Receiver
collection.

public class TestFeatureReceiver : SPFeatureReceiver

public override void FeatureActivated(SPFeatureReceiverProperties properties)

{
////This will the receiver collection of the list

using (SPWeb oWeb = (SPWeb)properties.Feature.Parent)

{
SPList oList = oWeb.Lists[strListName];

SPEventReceiverDefinitionCollection oEventDefColl = oList.EventReceivers;

////Set the values for the Definition object

string strAssemblyName = "TestEventHandler,Version=1.0.0.0, Culture=neutral, PublicKeyToken=ab011vdd6a7bfaba2";

string strClassName = "TestEventHandler.TestEventHandler2;

string strReceiverName = "TestListEventHandler";

string strDefData = "Data";

int intSequenceNo = 2001

////Create the Definition object

SPEventReceiverDefinition oEventDef = oEventDefColl.Add();

oWeb.AllowUnsafeUpdates = true;
////Set the properties

oEventDef.Name = strReceiverName;
oEventDef.Assembly = strAssemblyName;
oEventDef.Class = strClassName;
oEventDef.Data = strDefData;
oEventDef.SequenceNumber = intSequenceNo;
oEventDef.Type = SPEventReceiverType.ItemAdded | SPEventReceiverType.ItemUpdated | SPEventReceiverType.ItemDeleting;
oEventDef.Update();
oList.Update();
oWeb.Update();
oWeb.AllowUnsafeUpdates = false;
}
}

public verride oid FeatureDeactivating(SPFeatureReceiverProperties properties)

{
////This will remove from the receiver collection of the list

string strReceiverName = "TestListEventHandler";

using (SPWeb oWeb = (SPWeb)properties.Feature.Parent)

{
SPList oList = oWeb.Lists[strListName];

SPEventReceiverDefinitionCollection oEventDefColl = oList.EventReceivers;

Guid oGuid = new Guid();

foreach (SPEventReceiverDefinition oDef in oEventDefColl)

{

if (oDef.Name == strReceiverName)

oGuid = oDef.Id;

}

if (oGuid != null)

oEventDefColl[oGuid].Delete();

} }

For more about the SPEventReceiverDefinition Class

http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.speventreceiverdefinition.aspx

 

  1. Event Handler Class 

Event handler class would inherit the base class and contain the custom code under.....

public cass TestEventHandler: SPItemEventReceiver

public Oerride
void ItemAdded(SPItemEventProperties properties)

public Oerride
void ItemUpdated(SPItemEventProperties properties)

This remains the same.

HaPpY CoDiNg... (Aurum)

Wednesday, April 6, 2011

How to create Item Event Receiver (SPItemEventReceiver)

Another piece of work again. L.. No worries.. would do this in no time. I will be very short and just focus on code. While creating this Event Handler I have used only 3 files.

  1. Feature.xml
  2. Elements.xml
  3. Event Handler class (event handler class inhering from SPItemEventReceiver)

Let us how the code works

Feature.xml
The feature file will remain very simple, only with the basic details.

<?xml version="1.0" encoding="utf-8"?>
<Feature Id="62B66824-3AE2-4320-9949-6B59ED862C64"
Title="TestEventHandler"

Description="Adding/updating/deleting of any item in list"

Version="1.0.0.0"

Hidden="FALSE"

Scope="Web"

DefaultResourceFile="core"

ImageUrl ="NEWSPG.GIF"

xmlns="http://schemas.microsoft.com/sharepoint/">

<
ElementManifests>
<ElementManifest Location="elements.xml"/>
</ElementManifests>
</Feature>

The feature will be very simple and straight forward, nothing special about this except mentioning the element manifest. 

Elements.xml
The elements.xml will hold all the receiver information. The handler assembly and class information would be placed here to execute the events.

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns=http://schemas.microsoft.com/sharepoint/>
<Receivers ListTemplateId="100">
<Receiver>
<Name>AddingEventHandler</Name>
<Type>ItemAdded</Type>
<SequenceNumber>10000</SequenceNumber>
<Assembly>TestEventHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ab011vdd6a7bfaba2</Assembly>
<Class>TestEventHandler.TestEventHandler</Class>
<Data></Data>
<Filter></Filter>
</Receiver>
<Receiver>
<Name>UpdatedEventHandler</Name>
<Type>ItemUpdated</Type>
<SequenceNumber>10000</SequenceNumber>
<Assembly>TestEventHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ab011vdd6a7bfaba2</Assembly>
<Class>TestEventHandler.TestEventHandler</Class>
<Data></Data>
<Filter></Filter>
</Receiver>
<Receiver>
<Name> Delete</Name>
<Type>ItemDeleting</Type>
<SequenceNumber>10000</SequenceNumber>
<Assembly>TestEventHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ab011vdd6a7bfaba2</Assembly>
<Class>TestEventHandler.TestEventHandler</Class>
<Data></Data>
<Filter></Filter>
</Receiver>
</Receivers>
</Elements>

Here on any item added/updated/deleted the event will fire in the class mentioned below <Class>TestEventHandler.TestEventHandler</Class> would handle the events.

Even Handler Class 

Event handler class would inherit the base class and contain the custom code under.....

public class TestEventHandler: SPItemEventReceiver

public override void ItemAdded(SPItemEventProperties properties)

public override void ItemUpdated(SPItemEventProperties properties)

The SPItemEventReceiver class is not instantiated but the item event receiver class of a custom event handler must derive from this class and override its methods for the event types that are handled.

namespace Example_Namespace

{

public class Class_Name : SPItemEventReceiver

{

public override void ItemAttachmentAdded(SPItemEventProperties properties)

{

using (SPSite oSiteCollectionEvent = new SPSite(properties.SiteId))

{
SPWeb oSiteEvent = oSiteCollectionEvent.OpenWeb(properties.RelativeWebUrl);
SPListItemCollection oItemsEvent = oSiteEvent.Lists[properties.ListTitle].Items;
}

using (SPSite oSiteCollection = new SPSite("http://Top_Site"))
{
SPWeb oWebsite = oSiteCollection.OpenWeb("Website_Name");

SPList oList = oWebsite.Lists["Announcements"];

SPListItemCollection collListItems = oList.Items;

SPListItem oItem = collListItems.Add();

oItem["Title"] = properties.UserDisplayName + " added an attachment to " + oItemsEvent[properties.ListItemId].Title + " in list " + properties.ListTitle + " at " + properties.WebUrl;

oItem.Update();

} } } }

HaPpY CoDiNg... (Aurum)