aarebrot.net Frode's blog on Sharepoint and other stuff

Creating custom list event receivers in SharePoint 2007

Posted on August 11, 2010
VN:F [1.9.22_1171]
Rating: 5.0/5 (3 votes cast)

I'm working on a project these days where the requirements are to store a bunch of files in a document library, and then sync "published" files to another document library. We're probably going to end up using workflows to accomplish this because we only want approved documents to be synced. Right now however we're just in the elaboration stage of the project, so I was looking into whipping up a quick and easy way to sync files between document libraries. I chose the most obvious way, which was using list event receivers.

I've created event receivers before, but never ones on actual list items. So I figured I should probably jot down some notes because I'll probably want to go back and do it again at a later point.

I started with an already existing list definition (because that's what I wanted to add my event to). Then make sure you add a reference to the Microsoft.SharePoint.dll. You can find the dll in the "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI" directory.

Adding a reference to Microsoft.SharePoint.Dll

The full directory path to Microsoft.SharePoint.Dll.

Once that's done you need to create a couple of new files. Create a new class code file at the root of your project (or in a directory if you want stuff to be neat and organized) and also create an empty xml file in your feature folder.

Overview of List EventReceiver project

Adding the CopyDocumentToLibrary.cs and EventReceivers.xml files.

Ok, so far so good. Now we've got to wire up the class to be an event receiver. Crack open the file and delete all the using statements. Add a new one to the Microsoft.SharePoint namespace, and adjust the namespace and class name to your preference. Then make your class inherit the SPItemEventReceiver. You should be looking at something like this:

using Microsoft.SharePoint;

namespace Client.SpiManuals.RevisionLibrary
{
    public class CopyDocumentToLibrary : SPItemEventReceiver
    {

    }
}

Good job! You now have an event receiver. An empty event receiver that's not hooked up to anything, but an event receiver non-the-less. Ok, what next. Well, maybe we should choose what event we want to listen to. The way to do that is to override a method. The easiest way to figure out what kind of events you can listen to is to use IntelliSense. Just start typing, and magic will show the way:

Picking a method to override...

Using IntelliSense, we can easily see all the available methods we can override

In this case, I'm going to choose the ItemCheckedIn method. So we should end up looking like this:

using Microsoft.SharePoint;

namespace Client.SpiManuals.RevisionLibrary
{
    public class CopyDocumentToLibrary : SPItemEventReceiver
    {
        public override void ItemCheckedIn(SPItemEventProperties properties)
        {
            base.ItemCheckedIn(properties);
        }
    }
}

Next let's hook up our list to use our new fancy receiver. Open your Feature.xml and add an element manifest reference to your newly created xml file.

<?xml version="1.0" encoding="utf-8"?>
<Feature Id="{0D8B59F8-B7C6-44AA-A609-9E754F2BF7C2}"
   Title="$Resources:Feature_Name;"
   Description="$Resources:Feature_Description;"
   Version="1.0.0.0"
   Scope="Web"
   Hidden="FALSE"
   DefaultResourceFile="Client.SpiManuals.RevisionLibrary"
   xmlns="http://schemas.microsoft.com/sharepoint/" >
  <!-- We don't want this to be activated unless the Content Type / Site Column feature is activated -->
  <ActivationDependencies>
    <ActivationDependency FeatureId="{851C8139-1DBC-44e5-BA41-2D11BB7CF4F3}"/>
  </ActivationDependencies>
  <ElementManifests>
    <ElementManifest Location="EventReceivers.xml"/>
    <ElementManifest Location="RevLibTemplate.xml" />
    <ElementManifest Location="RevisionLibrary\RevLibInstance.xml" />
    <ElementFile Location="RevisionLibrary\EditDlg.htm" />
    <ElementFile Location="RevisionLibrary\FileDlg.htm" />
    <ElementFile Location="RevisionLibrary\Repair.aspx" />
    <ElementFile Location="RevisionLibrary\schema.xml" />
    <ElementFile Location="RevisionLibrary\Upload.aspx" />
    <ElementFile Location="RevisionLibrary\Combine.aspx" />
    <ElementFile Location="RevisionLibrary\AllItems.aspx" />
    <ElementFile Location="RevisionLibrary\WebFldr.aspx" />
  </ElementManifests>
</Feature>

Notice line number 15. That's where we're pointing to our new event receiver file. Now open your EventReceivers.xml file. If you want to read the documentation on how to create this file, check out this MSDN article. You can pretty much copy and paste the example in that article, and adjust it to your needs.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Receivers ListTemplateId="10001">
    <Receiver>
      <Name>CopyDocumentToLibrary</Name>
      <Type>ItemCheckedIn</Type>
      <SequenceNumber>10000</SequenceNumber>
      <Assembly>RevisionLibraryEventReceiver, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</Assembly>
      <Class>RevisionLibraryEventReceiver.CopyDocumentToLibrary</Class>
      <Data></Data>
      <Filter></Filter>
    </Receiver>
  </Receivers>
</Elements>

Ok, some brief explanation is probably needed here. The ListTemplateId attribute in the Receivers tag refers to the Type attribute in your ListTemplate tag in your list definition. In my case, it's in the RevLibTemplate.xml which looks like this:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <ListTemplate
       Name="RevisionLibrary"
       Type="10001"
       BaseType="1"
       OnQuickLaunch="TRUE"
       SecurityBits="12"
       Sequence="301"
       DisplayName="$Resources:List_RevisionLibrary_Title;"
       Description="$Resources:List_RevisionLibrary_Description;"
       Hidden="True"
       EnableModeration="True"
       VersioningEnabled="True"
       Image="/_layouts/images/itdl.gif" />
</Elements>

This is how SharePoint knows which list to hook up the event receiver to. So basically, every list that uses this list template will have the event receiver hooked up.

Other than that, make sure the Type tag matches the method you overrode in the event receiver class (ItemCheckedIn, in my case). Also make sure that your Assembly and Class tags point to the correct dll and namespace. If you're not sure what to put in the Assembly tag, build your project and open the resulting dll with Reflector. Copy and paste the Name from the yellow area when you have your dll selected.

How to find the assembly name

Our assembly name, complete with version, culture and public key token

Now your event should be hooked up to the ItemCheckedIn event of your list. Of course, it doesn't do much quite yet, so let's add some meat to our code.

using Microsoft.SharePoint;

namespace Client.SpiManuals.RevisionLibrary
{
    public class CopyDocumentToLibrary : SPItemEventReceiver
    {
        public override void ItemCheckedIn(SPItemEventProperties properties)
        {
            base.ItemCheckedIn(properties);

            using(SPSite targetSite = new SPSite("http://sevm955603:15000"))
            using(SPWeb targetWeb = targetSite.AllWebs["DepartmentsAndDivisions/TransET"])
            {
                foreach(SPFolder folder in targetWeb.Folders)
                {
                    if (folder.Name == "PublicationLibrary")
                    {
                        try
                        {
                            folder.Files.Add(
                                properties.ListItem.File.Name,
                                properties.ListItem.File.OpenBinaryStream());

                            folder.Update();
                        }
                        catch (Exception ex)
                        {
                            // handle exception here
                        }
                    }
                }
            }
        }
    }
}

I've got a bunch of hard-coded paths in here, which is obviously not a great thing, but this is just to show the basic idea, so bear with me. Basically what we're doing here is we're opening the target Site Collection, and the Web contained within that collection where we want to save the file.

Then we iterate through all the folders (lists) in that Web until we find the one we're interested in. In this case, it's our PublicationLibrary. Once we find the library we're interested in we add the file to the folder using the Add method, passing in the file's name and binary stream. Lastly, we update the folder for the changes to take effect.

Now open up the revision library and upload a file. Check the document out, then check the document back in, and boom. Instant synchronization.

Files synchronized across two document libraries

Both document libaries showing the synchronized file. Notice in the URLs that they are different libraries on two different Site Collections.

This is a very basic example, but hopefully you can use it to build your own list event receiver.

Creating custom list event receivers in SharePoint 2007, 5.0 out of 5 based on 3 ratings
Comments (2) Trackbacks (0)
  1. Hi,Very Usful article.thank you very much.keep sharing knowledge.

  2. This article gave me an insight into SharePoint from scratch.Its Simple to Understand and complete.I Enjoyed learning. Thanks for sharing with us. Its really helpful for beginner as well as developer. Check out this link too its also helped me to complete my task….

    http://mindstick.com/Articles/05f028f6-0d22-48e5-88bc-31f7be85c0ea/?Event%20Receiver%20in%20SharePoint%202010

    Thanks


Leave a comment

 

No trackbacks yet.