2011-03-17

Getting BeforeProperties and AfterProperties in Event Receivers

You're here because you're trying to find away of comparing values of a record before or after saving it in an event receiver, and BeforeProperties and AfterProperties are giving you null, right? Well chances are you searched and found posts about saving the values to a cache, and a lot of other rubbish... I know I did.

Anyway the proper way of doing things is real simple, and I stumbled upon it using Powershell to check my event receivers.

SPEventReceiverDefinition has a Synchronization property.

An Asynchronous event passes the objects to another thread and you lose the BeforeProperties and AfterProperties.
A Synchronous event keeps the thread and you can access the BeforeProperties and AfterProperties.

In my case after specifying the event receiver as Synchronous I was able to compare existing values with values in properties.AfterProperties on an Receiver Type = ItemUpdating.

So to set a Receiver as Synchronous, just add Synchronous to your definition (elements.xml) or in code set the Synchronization property.

Eg:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Receivers>
<Receiver>
...
...
<Synchronization>Synchronous</Synchronization>
</Receiver>
</Receivers>
</Elements>




4 comments :

  1. hi rayone, i have a problem and i can´t find a solution for this...maybe you can help me.
    my customer wants use windows explorer view to drag and drop SPListItems, at this point everything is OK, but he wants original values of "Modified" and "ModifiedBy" fields (in source list) be the same values in destiny list. the problem is when you are in windows explorer view and you do a dragNdrop action...modifiedBy field has the user logged in windows.
    i have an eventReceiver for that destiny list to change this values overwritting "itemAdding" and "itemAdded" events and my code looks like :
    if (listItem["Author"] != null)
    { listItem["Editor"] = listItem["Author"];
    listItem.update();}

    when listItem.update is running it through an exception saying windows logged in user has modified that item.

    any ideas??? thank you very much.

    Josete.

    ReplyDelete
  2. Josete.

    You need to use the SPListItem.SystemUpdate() Method:

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

    ReplyDelete
  3. Hi,

    It seems that this is not working... In your post you said that you test with a ItemUpdating event. But this item is synchronous by default and get access to AfterProperties and Item. But if you try this with a ItemUpdated tagged as synchronous, afterproperties and item get the same value (as the item is already commited to the database) and beforeproperties is not null but contains no value.

    Maybe am i missing something...

    ReplyDelete
  4. In the ItemUpdating override I first call
    base.ItemUpdating(properties);

    Then pass "properties" down to my methods where I compare:
    properties.ListItem[properties.List.Fields[gField].StaticName]
    with
    properties.AfterProperties[properties.List.Fields[gField].StaticName]

    ReplyDelete