The trouble with editing items on synchronous add-events

As I have written once or twice (see here) before, I create a lot of functionality using event receivers.

Now when you are adding new items you might want to fill field values based on either the event or external data, so you will use a synchronous adding event (SPEventReceiverType.ItemAdding). Once you get the item (SPListItem item = properties.ListItem) and you want to edit the item you should use a disable-event-firing strategy (Eventfiring) if appropriate (trigger event on edit, not insert) – this is usually appropriate when you know conditions to be false on insertion or if you already call methods from insert events that would be duplicated by the edit-event.

Now the tricky part of the editing is that if you do it wrong, you will get cryptic messages (“Microsoft.SharePoint.SPException: Save Conflict Your changes conflict with those made concurrently by another user. If you want your changes to be applied, click Back in your Web browser, refresh the page, and resubmit your changes.”). The reason for this is that the user who creates the item is not the same as the context the event receiver is running in as long as you use the standard edit-and-update-methods available.

So let’s do it the right way:

SPListItem item = properties.ListItem;
item["TheInternalFieldName"] = "TheCalculatedValue";
item.SystemUpdate(false);

So this little piece of code took me a long time to figure out. Let’s check out why it’s good and then, what you could have done wrong:
The first step is basic: get the item from the properties.
The second step is editing the item. Easy! The internal field name must exist and the calculated value should be something that fitts into the column. Bamm! There you go. You could have done this by yourself so far.
Now, here is the important part: item.SystemUpdate(false).
It’s a system-user update with false as parameter.
If you check msdn you will find there are two SystemUpdate-methods. Web-Objects have the Update (non-overloaded: Update()), List-Objects have the method Update (overloaded: Update(), Update(boolean)) and items also have SystemUpdate (overloaded: SystemUpdate(), SystemUpdate(boolean)).
SystemUpdate(false) is exactly what you want as the explanation says: Updates the database with changes that are made to the list item without changing the Modified or Modified By fields, or optionally, the item version.
Okay. So you’re safe. One thing less to worry about. But why? Why? If it’s that simple why am I writing a whole article dedicated to this?
Well I have seen the error-messages. I need to reproduce them, because it has been a while since then but the essence is: usually you use update, as it is natural for lists and web and you use it without parameter, because usually you don’t have it (web) or you don’t need it (list – only when migrating data). So until you understand why SystemUpdate with boolean is important, a whole day can go by.

Basically I’m saying the same as Karine Bosch. Just found it while searching for error messages!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: