Skip to main content

Creating custom list event receivers in MOSS 2007

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.

                                                                           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.

                                                                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:
Code:

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:
 
                                                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:
Code:

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.
Code:

<?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.
 Code:

<?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: 
 Code:
<?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.
 
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.

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.

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

Comments

  1. Hi, I do believe this is an excellent website.
    I stumbledupon it ;) I may return once again since I bookmarked it.
    Money and freedom is the greatest way to change, may you be rich and continue to help other people.


    My website weight loss tea

    ReplyDelete

Post a Comment

Popular posts from this blog

Tab Control in Asp.Net

Scenerio: I need your help in designing tab control in   asp.net .My requirement is I need a tab control in   asp.net (C#) like  for example goto my computer ,right click c drive and select properties.we get tabs like general,security etc....... like that i need to design one tab control(no need of any rightclick) in my web page and the database table columns should come as tabs and inseide the tab data of that particular column should come.   Example:Employee master tab1:Employee name.........his name in the tab tab2:Age.............his age tab3:Address........his address   Solution:   You can do this using a simple div <style type="text/css"> .tabs         {             position: relative;             height: 20px;             margin: 0;   ...

AI and Microsoft: Revolutionizing Efficiency in Nonprofit Organizations

  How AI and Microsoft Enhance Efficiency in Nonprofit Organizations In today’s fast-paced world, nonprofit organizations face unique challenges—limited resources, increasing demands, and the constant need to do more with less. But what if technology could be the game-changer they need? In my latest research paper,  "How AI and Microsoft Enhance Efficiency in Nonprofit Organizations" , I explore how cutting-edge technologies like Artificial Intelligence (AI) and Microsoft’s innovative tools are revolutionizing the way nonprofits operate. From streamlining administrative tasks to enhancing donor engagement and optimizing resource allocation, AI and Microsoft’s solutions are empowering nonprofits to focus on what truly matters—their mission. This paper dives deep into real-world examples, practical applications, and the transformative potential of these technologies. Whether you’re a nonprofit professional, a tech enthusiast, or simply curious about the intersection of technolo...

Social tagging overview in Sharepoint 2010

A tag is a word or phrase that identifies an individual piece of information according to a set of attributes or criteria. Tags make it easy to find and share information about a specific subject or task. Social tagging helps users categorize information in ways that are meaningful to them. Social tagging can improve the quality of search results by filtering against specific tags, and it can also connect individuals who want to share information with other users who have like interests. This article describes the social tagging features in Microsoft SharePoint Server 2010. This article does not describe how to configure social tagging features. It also does not discuss how to implement social tagging features as part of an overall social media strategy for an enterprise. About using social tagging features Social tagging features help users to share information and to retrieve relevant, high-quality content more efficiently. Such sharing encourages collaboration and b...