Synchronous and asynchronous Event Handlers


In SharePoint 2007 it is possible to handle events that occur on list items. These types of events come in two flavours: synchronous and asynchronous.

  • Synchronous: happens 'before' the actual event, you have the HttpContext and you can show an error message in the browser and cancel the event
  • Asynchronous: happens 'after' the actual event, there's no HttpContext  and you cannot directly show an error message or cancel the event

By subclassing Microsoft.SharePoint.SPItemEventReceiver you can override the desired "event" methods.

  • Synchronous: methods ending with '-ing' (ItemAdding, ItemUpdating, ...)
  • Asynchronous: methods ending with '-ed' (ItemAdded, ItemUpdated, ...)

If you implement an override method you might want to place your code between the following lines to avoid raising other events unwantedly (and possibly causing an infinite loop).

this.DisableEventFiring();
...
this.EnableEventFiring();

Each override method has a parameter of type Microsoft.SharePoint.SPItemEventProperties that contains the item and event properties available for use. There's a bug in the SPItemEventProperties.AfterProperties dictionary that appears empty for synchronous events but it isn't. You can iterate over the dictionary to read and write to this collection ! This means that you can modify some of the inputted metadata before the actual item is stored in the list.

The thing to remember here is that the dictionary uses the field internal name as key, so field 'My custom field' could have an internal name such as 'My_x0020_custom_x0020_field'.

You can get the internal name of a field by using a tool like Stramit SharePoint 2007 Caml Viewer or as follows:

  • Navigate in the browser to the 'Edit Page' of the List or Site Column
  • The URL contains the internal field name

Here's a code snippet that works for synchronous events that outputs the contents of the property dictionary to the screen. It cancels the event so it's not very useable for other purposes but it could come in handy to actually see what is used for metadata.

using System;
using System.Collections;
using System.Text;
using Microsoft.SharePoint;

namespace Vandest
{
     public class MyTestEventReceiver : SPItemEventReceiver
     {
          public override void ItemAdding(SPItemEventProperties properties)
          {
               StringBuilder sb = new StringBuilder();
               foreach (DictionaryEntry de in properties.AfterProperties)
               {
                    string key = de.Key.ToString();
                    string value = de.Value.ToString();
                    sb.AppendLine(key +
" -- " + value);
               }
               properties.Cancel =
true;
               properties.ErrorMessage = sb.ToString();
          }
     }
}

 
  • Categories:


Comments

Wednesday, 7 May 2008 12:45 by Meera
Hi Steve, We are using Asynchronous (ItemAdded and ItemUpdated) events in my project. We created one uploadfile.aspx page with uploadfile.cs file to upload the files into documentlibray and when ever we click on OK in this page we are redirecting the page to EditForm.aspx page, here we are updating some metadata for the file and we are using Itemadded and Itemupdated events to get the values in the EditForm.aspx page. So when ever we click on OK in the uploadfile.aspx page, we are getting "Save Conflict.......bla,bla,bla" error. Could you please suggest and send me the possible solutions to resolve this exception. Its very urgent for our team.........:( Thanks in advance.

Thursday, 8 May 2008 12:34 by Steven Van de Craen
Hey, Looking at your description it seems there's something wrong with your uploading code ? You'll have to debug through it to find the error. Maybe the file is uploaded as checked out (eg when there is required metadata) ?

Sunday, 23 Nov 2008 07:30 by JB
I have the following problem. My user does not like the page to have ERROR on it (as Header /Title) even if I have a full description in the error message. How do I modify the title to say other than ERROR?

Monday, 24 Nov 2008 02:15 by Steven Van de Craen
JB, I think you're out of luck there. You might try some redirect in the event handler but I'm pretty sure that will mess with the entire 'flow' and isn't adviseable.

Friday, 4 Dec 2009 05:32 by Manas
Hi Steven, I am having ItemAdded eventreceiver which basically modify the properties of the document. The problem is when user upload a document through Upload.aspx, it redirects to EditForm.aspx. So if ItemAdded event is completed before EditForm.aspx appears, everything is fine. But if EditForm.aspx appears first, then ItemAdded changes the properties in the back-end and if user clicks on OK on EditForm.aspx, he gets the error saying The file has been modified. Any help ? Thanks in Advance.

Wednesday, 28 Sep 2011 02:47 by Priyesh
Hi, I have a ItemAdded event reciever, i want to direct a user to some other url after i do some custom action on this event handler. After going through many forums i have understood that on asynchronous events we get HTTPContext as null and on synchronous event we get HTTPContext. Is their any way about redirecting user to a specific link on Asynchronous events. I have already tried this code of having ItemAdding event and setting the HTTPContext to the same type of variable and using the same in ItemAdded event. But it does not work. I have also tried SPUtiltity.Redirect. This also din't work. Please advice!! Thanks, Priyesh

Friday, 30 Sep 2011 10:48 by Steven Van de Craen
Hi Priyesh, in SP2010 you can register post-event handlers as synchronous. This might help you. See: http://wineya.blogspot.com/2010/03/binding-asynchronous-event-handlers-as.html

Friday, 30 Sep 2011 01:49 by Priyesh
Hi Steven, Thanks for a prompt reply on this. Actually i had a question whether this will work on moss 2007 as well. I guess it was my mistake and i forgot to mention that i am working on 2007 and not on 2010. Also i had a look at the blog that you have mentioned, it looks quiet helpful and says to added event handlers programmatically. But i am using WSP builder's Event Receiver template with my feature attached to it for registering event handler. Any thoughts on this Steven? Thanks, Priyesh

Sunday, 2 Oct 2011 09:01 by Steven Van de Craen
Hi Priyesh, this is only for SharePoint 2010. You can't do it for SharePoint 2007 in any way (code, feature xml, ...)

Monday, 14 Nov 2011 06:44 by Jithu
HI Steven, Thank you for you great explanation, However I would like you to have a look at the following code, where I stuck without any progress. Well I have a datasheet type list in SP2010. I have two fields. 1. Status (Text field) 2, Last Modified (Date field) and also other few columns. Now my requirement is that whenever I changes the Status field I need to change Last Modified field of that row/item with today's date. The Last Modified date should not change when other columns apart from Status column changes. I have created the following receiver code, public override void ItemUpdating(SPItemEventProperties properties) { this.EventFiringEnabled = false; if ((properties.ListItem["Status"] == null) || (properties.AfterProperties["Status"] == null)) { return; } else { string currentStatus = properties.ListItem["Status"].ToString(); string newStatus = properties.AfterProperties["Status"].ToString(); if (currentStatus != newStatus) { SPListItem oItem = properties.ListItem; oItem["Last Modified"] = DateTime.Now; oItem.SystemUpdate(); } } this.EventFiringEnabled = true; base.ItemUpdating(properties); } Well the event is firing and also the field Last Modified field is updating with current date. The problem is whene evr this event is firing I am getting a warning in the data sheet/ List saying "The user (Same user) has changed the data, hence my data cannot be committed, " It will ask for resolve and I am forced to discard my changes. I am very very new to SP. Please do help me to get this done !!

Tuesday, 15 Nov 2011 09:24 by Steven Van de Craen
Hi Jithu, you should really use a custom Date Field for that since you're intervening in the normal behaviour of SharePoint. If you still want to continue, you could try your action in an ItemUpdated (post) receiver that is registered Synchronously (new in SP2010 is that you can register post event receivers as synchronous instead of asynchronous).

Friday, 8 Mar 2013 10:17 by Anil
Hi Steven, Make the asynchronous event receiver to synchronous even event receiver by adding Synchronous tag in your elements.xml file

Friday, 8 Mar 2013 10:17 by Anil
Hi Steven, Make the asynchronous event receiver to synchronous even event receiver by adding Synchronous tag in your elements.xml file

CAPTCHA Image Validation