Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

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
share|improve this question

1 Answer 1

up vote 5 down vote accepted

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

share|improve this answer
    
Thank you, that was extremely helpful/informative. Here I thought BeforeProperties and AfterProperties were just read-only. Again, thanks for the info. –  gsmith140 Jul 24 '12 at 11:34
    
...and it works in the sandbox too! Thanks. –  Derek Gusoff Oct 17 '12 at 20:14

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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