Sharepoint 2007: List Events Practical Example: Creating a rigged survey!!

Posted on 7/30/2006 @ 10:55 AM in #SharePoint by | Feedback | 78399 views

Sharepoint 2007 supports various events on Lists. These events can be broadly classified into two categories - Synchronous and Asynchronous.

Synchronous events such as "ItemAdding" or "ItemUpdating" occur before the action has taken place. They occur synchronously, in other words, these are in the singular pipeline of events that must finish in order for the action to take place. This means, you can effectively cancel the occurring event, should you choose to do so.

Asynchronous events on the other hand, such as ItemAdded or ItemUpdated occur after the action has taken place. For instance, you may want to scrub the data after it has been entered, or you may want to email the administrator if a field has been added - as an FYI. These do not affect the pipeline of events.

It is important to note that there are events at numerous levels - at the item level, at the list level, site level and so on so forth.

So the obvious question is, "How can you tap into such events?"

Well, I am going to demonstrate that by creating a survey on my sharepoint site, and then rigging that survey LOL. :).

So go ahead and click on Site Actions -> Create

Then go ahead and create a new Survey as shown below:

Then go ahead and set up a survey, with one question -

"Is Sahil a good boy?"

With two possible answers "Yes"/"No" presented as a radio button choice to the user.

Now obviously, Sahil is a good boy, so you wouldn't want anyone saying anything else right? SHWEET!! So next I am going to go ahead and rig this survey so the user cannot answer "No", the only right answer is "yes".

To do so, I will need to tap into the ItemAdding event, and to do that, I will need to inherit from the SPItemEventReceiver and create my custom event receiver, and then override the ItemAdding method. Once I do that, I could then validate the data as necessary. The code can be seen below:

namespace ListReceiver
{
    public class SahilIsGood : SPItemEventReceiver
    {
        public override void ItemAdding(SPItemEventProperties properties)
        {
            SPList SahilSurvey = properties.OpenWeb().GetList("http://homepc/Lists/Sahil");
            string currentResponse =
                SahilSurvey.Items[SahilSurvey.Items.Count - 1]["Is Sahil a good boy?"].ToString();
 
            if (currentResponse != "Yes")
            {
                properties.ErrorMessage = "The only valid response is YES you nitwit!!";
                properties.Cancel = true;
            }
        }
    }

}

As you can see in the code above, I first get the appropriate survey (which is a list), and then I get a hold of the last Item added. And if the user said "No", I respond with a polite message saying "The only valid response is YES you nitwit!!" and effectively cancel his input.

Now since this is an SPItemEventReceiver, it will need to be placed in the GAC, so go ahead and strong name it and put it in the GAC.

GREAT!! Your Event receiver is setup, but you still can't use it. Why? Because you haven't bound it to your list yet. So lets do that next. You can do so by using a feature, or as I'm going to do it, using a simple Console Application. Here's the code:

SPSite site = new SPSite("http://homepc") ;
SPWeb
web = site.OpenWeb();
SPList
survey = site.Lists["Sahil"]; 

string assemblyName = "ListReceiver, Version=1.0.0.0, Culture=neutral, PublicKeyToken=dd4d54c05b75eae9";
string
className = "ListReceiver.SahilIsGood";

survey.EventReceivers.Add(SPEventReceiverType.ItemAdding, assemblyName, className);

Go ahead and run this, this will bind the Event Receiver to the Sahil survey list. Here is a helpful tip: If you're in the midst of debugging, you will have to do IISRESET frequently. This is because IIS will load the assembly from the GAC and won't pick up your changes.

Okay, now go ahead and take the survey. Just for kicks, I am going to click on "No" as my answer, which as I already mentioned is a thoroughly senseless and incorrect answer as shown below:

Now when you go ahead and click on "Finish Survey", Sharepoint is now smart enough to prompt you with the following message:

NICE !! :).

Again, this is something you couldn't do in Sharepoint 2003.

 

Thou shalt -

Sound off but keep it civil:

Older comments..


On 8/1/2006 6:54:39 PM Morgan Everett said ..
Great blog post. I listed all the different order of events. It was pointed out to me that the ItemAdded and ItemAdding events, don't fire on a Wiki Library. I'm not sure if that is a bug in Beta 2, or not. But, I hope they find it and fix it.


On 8/1/2006 11:48:19 PM Ishai Sagi said ..
This is wrong!


you are not checking the item being added, you are checking the last item already in the list. your code is correct if you change the event to "itemadded" but not as it is now in "itemadding".


Also, your code is not generic enough - please correct (see my post in http://spstips.blogspot.com/2006/08/bad-news-synchronous-list-events-bug.html)


On 8/2/2006 5:58:45 AM Sahil Malik said ..
Ishai,

I read your blogpost.

The proposed change to get the list is good. Anytime you can get away from hardcoding, that is a good thing.

The ListItem was null - I ran into the same issue. No I cannot use the ItemAdded event because I need to cancel the input, so I must use a synchronous event. This happens only in this kind of list however - if you set up a simple custom list, it seems to work.

Anyway, I did test my code, and it seemed to work. I know what you mean however - why should I have to do listitems.count? Why can't I just get a hold of the current ListItem being added. :). Maybe it's a bug - who knows.

Sahil


On 8/2/2006 6:00:45 AM Sahil Malik said ..
Morgan,

I ran into the same issue (Wiki Library). The behavior of these events seems to be specific to the kind of list you pick. Maybe it's a bug (I hope it is), but if it is not, a good documentation on what fires on what would be helpful eh? :)

Sahil


On 8/2/2006 5:04:14 PM Szalek said ..
Why don't you get item data from EventArgs? For ItemAdding, ItemUpdating and so on list item data are contained in SPItemEventProperties.


On 8/2/2006 6:41:43 PM Sahil Malik said ..
Szalek,

Thats the issue. Those thingies were null :).


On 8/13/2006 8:03:05 AM Kay Adeyemi said ..
Sahil you can get at the items being added to the list by overriding the ItemAdding, ItemAdded, ItemUpdated etc ...The event args to these methods is a property which contains alot of information... Here is a snippet of code that works for me ..

public override void ItemAdded(SPItemEventProperties properties)


{


MarkItemAsComplete(properties);


}

void MarkItemAsComplete(SPItemEventProperties properties)


{


SPListItem taskItem = properties.ListItem;


if (taskItem != null)


{


taskItem["Status"] = "Completed";


taskItem.Update();


}


}


}

The most important line here is where the SPlistitem is being initialised ..Hope this helps...


On 8/13/2006 12:25:05 PM Sahil Malik said ..
Thanks Kay. Did you test it on a "Survey" list? The behavior seems to differ. The ItemAdded works, but what I really need is ItemAdding.


On 9/18/2006 1:54:32 AM Ishai Sagi said ..
there is a small bug in here, the line


SPList survey = site.Lists["Sahil"];


should be


SPList survey = web.Lists["Sahil"];


On 9/18/2006 6:52:19 AM Sahil Malik said ..
Ishai - did something change in B2TR? The above worked in B2.


On 9/27/2006 7:22:49 PM Ishai Sagi said ..
I am publishing an update now. the bottom line - this didnt work in B2 and doesnt work in TR and will not work in release. Microsoft acknoleged this as a by-design bug (you should change the article to use ItemAdded) for list items (but not for documents).


On 9/27/2006 7:25:14 PM Ishai Sagi said ..

On 11/10/2006 11:48:35 PM Sunny Rajpal said ..
Wht if i have to make disble a textbox at the time of onload event of a list which event will work for me in that case can u answer me its really very urgent for me


On 11/23/2006 1:19:51 AM AK said ..
Hi

I am new to Sharepoint 2007 !!


How do I get the question from the Survey by capturing ItemAdded event?


I need to capture the question from Survey and display it in my custom webpart.


On 10/21/2007 1:17:57 PM Sreenath said ..
im using item added event to trap when a file is added in document library.... it works fine.....

i wud like to trap the event when a new folder is created in sharepoint document library....how do i do this??

thanks


Sai


On 12/17/2007 6:06:26 PM Marten said ..
Not sure why no one else picked it up, but the line: "SPList survey = site.Lists["xxx"];" should be "SPList survey = web.Lists["Documents"];"

Cheers,
Marten

On 12/17/2007 8:26:31 PM Sahil Malik said ..
Marten -

Actually this example doesn't work. I've kept it up here because it is still a very good reference to event receivers in general. This used to work in a pre-beta build, and since then accessing the current item wasn't possible via synchronous events. Anyway, the true value of demonstrating an event receiver seems to come through in this article, so so far I've left it.

SM

On 2/1/2008 6:15:25 AM Sadanand Sudeer said ..
This is regarding, what seems to be a defect WSS 3.0 Object Model. I happened to stumbeled apon it while modifying the DBLayer to suport Drag-Drop of folders into explorer view of Document Library.

Here is a brief description of my observations when a folder is droped into the explorer view:


1. If you override that ItemAdding event the AfterProperties attribute of properties object provided by WSS is empty, adding values into the collection does updated the changedfileds collection in the AfterProperties collection, but is not persisted in the respective fields and hence is not visible in the document library view. This though works fine for Files (any type). It also works fine if the folder is created using the AddFolder feature of the DcumentLibrary view.

2. If you override the ItemAdded event the ListItem Object in the Properties object provided by WSS is null, while it should provide the reference to the ListItem which has been added.


On 2/7/2008 2:50:21 PM chandra said ..
1)Hi, i am developing a survey application using survey template in wss 3.0,


I created workflow using sharepoint designer and i was trying to initiate that workflow in- response with my survey result. But "The status of a workflow appears as "Failed to Start" ".


I have seen a kb article:http://support.microsoft.com/kb/926370


It says that "starting a workflow from a survey response is not supported windows


sharepoint services 3.0.


2)Can i find a solution for my problem if i use event handlers in my survey list.


On 5/12/2008 3:25:41 AM Dima said ..
THANK YOU!!!


On 7/15/2008 5:10:07 PM sreenivas said ..
Hi Sahil,


I have created a Custom List Template. I wanted to execute an receiver when the List is created using the above custom List Template. How can i achieve this ?


On 9/5/2008 2:41:32 AM Pritesh said ..
Good One Examle for Beginner ...


On 9/10/2008 12:53:40 PM Brian said ..
As an absolute beginner...where, in Sharepoint, do I place the namespace ListReceiver procedure code please?

Is it C?

THANKS


On 9/10/2008 1:32:27 PM Sahil Malik said ..
Brian - In the GAC.


On 9/18/2008 5:56:52 PM Fjtorres said ..
-----


<>.<>


I have several reports published on my SharePoint 2007 Site. What I like to do is, when a user open's a close a report give the user a pop-up page with a survey. Each report will have there own survey. Can I do this with the Survey feature in MOSS 2007 or Do I have to dig in the code???


<>.<>


-----


On 9/18/2008 6:03:21 PM Madhuri said ..
Hi Sahil,

I have a question: I have a document library which has a workflow associated with it. Once the document is completely approved I want to update and add entries into Active directory. I was wondering if its possible to create an Event Receiver which gets fired when the document is approved . Is it possible to create such an event?

Thanks!!!


Madhuri


On 10/2/2008 8:09:21 AM PJC said ..
Is it possible to kickoff a workflow whenever a list (not list item) with a given content type is created?


On 11/27/2008 1:29:28 PM Cristian said ..
Hi Sahil.


Its possible to change a document name using Sharepoint EventHandlers (WSS 3.0)?


Any sniped code to suggest?

Cristian


On 3/18/2009 6:21:15 AM surendra singh said ..
Hi,

How to change generice message in sharepoint survey list


"You are not allowed to respond again to this survey" change

"You have suceffuly finish your survey"

Thanks


On 7/23/2009 5:17:51 PM sid said ..
Sahil,

I am supposed to syncronize an external database table with sharepoint list.


BDC is one option but I don't have enterprise CAL.

I am thinking of using SPList events (added,deleted,updated) to do syncronization (one way - list to table)

Would this approach be ok? Or there are options available?

Thanks,


Sid


On 7/24/2009 3:52:32 PM sid said ..
Hi All,

Adding a eventreceiver using console applicatoin would have worked well but what do we do if we want to remove the same using such a quick and easy (some people call it dirty) way.

There are two ways: (1) either use the GUID to remove the event (which majority of the people would not be knowing) (2) As shown below

in the same console application replace this line


"survey.EventReceivers.Add(SPEventReceiverType.ItemAdding, assemblyName, className);"

with

foreach (SPEventReceiverDefinition erd in survey.EventReceivers)


{


if (erd.Assembly == assemblyName && erd.Type == SPEventReceiverType.ItemAdding)


{


erd.Delete();


}


}

Thanks,


Sid


On 7/24/2009 3:54:28 PM sid said ..
Hi All,

Adding a eventreceiver using console applicatoin would have worked well but what do we do if we want to remove the same using such a quick and easy (some people call it dirty) way.

There are two ways: (1) either use the GUID to remove the event (but majority of the people would not be knowing what was the GUId of their even was!) (2) As shown below

in the same console application replace this line


"survey.EventReceivers.Add(SPEventReceiverType.ItemAdding, assemblyName, className);"

with

foreach (SPEventReceiverDefinition erd in survey.EventReceivers)


{


if (erd.Assembly == assemblyName && erd.Type == SPEventReceiverType.ItemAdding)


{


erd.Delete();


}


}

Thanks,


Sid


On 8/25/2009 2:38:31 AM Raj said ..
You are attaching this code using a console application. Can you also explain how do we do using feature.


On 10/16/2009 9:48:57 AM Sachin Kainth said ..
Hi Sahil,

I've been trying all day but can't get error messages (using properties.ErrorMessage) to appear on my screen. I keep getting SharePoint's message which is "An event receiver has cancelled the request". Any ideas? I'm using a document library and uploading a document.


On 1/8/2010 2:19:32 AM Polika said ..
I have a doubt... W.r.t binding the event reciever to the SPSite. The site path will change when we make the SP site live ... will my biding still work.


Secondly if i have an extended site on another port .. do i have to do another bind to it since it at different port


On 1/19/2010 4:49:10 AM Yash Dogra said ..
Can u please elaborate Events at site level in MOSS...????


On 6/4/2010 11:24:26 AM Matt said ..
When I run this code, using ItemUpdated and site.Lists = Calendar, the event receiver does not fire. I have tried to throw an ex.message after the public override, but when I run the workflow(and make a change)I get no message. Does anyone have any suggestions on why?