2

A user has a list that has a couple fields that are often updated. He wants to store the prior values in some other fields on the item when the item is updated (yes, I know versioning would be easier, but I'm at his mercy here). So I need to move the old values of these fields to different fields.

I am using an ItemUpdating event receiver (in 2010). The code seems pretty straightforward, but I can't get the the fields to update. Even when hard-coding the values, the code runs successfully but the values aren't saved. I tried ItemUpdated, which will update the values, but it's not going to work for my solution. Am I missing something here? Sample:

Public Overrides Sub ItemUpdating(properties as SPItemEventProperties)
    MyBase.ItemUpdating(properties)

    Dim currentItem As SPListItem = properties.ListItem

    Using Web As SPWeb = properties.OpenWeb()
        Me.EventFiringEnabled = False
        Web.AllowUnsafeUpdates = True

        currentItem("PriorPrice") = 5.25

        currentItem.SystemUpdate(False)
        Web.AllowUnsafeUpdates = False
        Me.EventFiringEnabled = True

    End Using
End Sub

1 Answer 1

10

You cannot update properties.ListItem in the ItemUpdating event. That property contains the original values, and are for reference only (not saved back). You can use that to get your prior values.

What you want to update is properties.AfterProperties, where the changed values are stored. Note that that property is a basic array of string (or more exactly a IEnumerable), not a SPListItem, although you access its values in a similar manner:

properties.AfterProperties["PriorPrice"] = 5.25;

Anything you put in this array will be used to update your item when the event completes. Also note that in properties.AfterProperties["FIELD"], FIELD must be the Title (or Display Name) of the field. Also beware that SPField.Title is not necessarily unique in the list.

Refer to this excellent blog post from Randy Williams for a complete overview of which property to use with each event : Working with BeforeProperties and AfterProperties on SPItemEventReceiver

Side note #1: You should never open a new SPWeb inside a synchronous event receiver, as this is potentially a very costly operation. In your case, access instead the current web by using properties.Web, and do not dispose of it (do not put inside a using block).

Side note #2 : You should not set SPWeb.AllowUnsafeUpdates unless you are specifically trying to update an item inside a GET request. It is not your case in the code you show, you should be able to directly edit properties.AfterProperties. You should avoid manipulating SPWeb.AllowUnsafeUpdates lightly as it exists to protect against vulnerabilities. Refer to : "What You Need To Know About AllowUnsafeUpdates" parts I and II

1
  • Thank you, that was extremely helpful/informative. Here I thought BeforeProperties and AfterProperties were just read-only. Again, thanks for the info.
    – gsmith140
    Commented Jul 24, 2012 at 11:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.