Monday, March 24, 2008

Update SPListItem Created By and Modified By Fields

Well I thought I would have the simple task which was not so simple. I had a requirement to allow users to make anonymous submissions which I wanted to store in a SharePoint List. Simple enough right?

I needed to create a web part and in that web part I needed to create a SPListItem for designated list. In a previous blog I had created an archive method where I had set the modified by and last updated but apparently I had made a mistake. The code will absolutely work if I am logged in as an administrator however if I am logged in as user who is part of a member group with contributor rights I cannot set the created or modified by fields. This made sense for what I was doing at the time but now I needed to allow normal every day collaboration users to do this operation. As well, the users in the members group should not have rights to edit or delete items in the list items; just add. It is simple enough to break the security inheritance on the list and associate members of that group to a custom permission level. However I wanted to avoid doing that.

I did some searching around and found the following:

These show you how to update the created and modified fields but did not help me in my quest.

I found some stuff that a guy wrote on creating an impersonation utility:

However that was going really overboard. In WSS 3.0 you now have the ability to SPSecurity.RunWithElevatedPrivileges. Now I had tried this in my web part but it was not going so well. However I moved the logic to a custom ItemAdded event handler on the list and that did the trick. Plus it is better to put the logic of changing the created and modified by on the list itself because if direct submissions are made on the list then logic is centrally located.

The event handler is below:


public class InsertEventHandler : SPItemEventReceiver
{

public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
ChangeSubmittedBy(properties);
}

private void ChangeSubmittedBy(SPItemEventProperties properties) {

Guid siteID = properties.ListItem.ParentList.ParentWeb.Site.ID;
Guid webID = properties.ListItem.ParentList.ParentWeb.ID;
Guid listID = properties.ListItem.ParentList.ID;
Guid newItemID = properties.ListItem.UniqueId;

SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(siteID))
{
using (SPWeb web = site.OpenWeb(webID))
{
SPList questionList = web.Lists[listID];
SPListItem listItem = questionList.Items[newItemID];

SPFieldUserValue oUser = new SPFieldUserValue(
web, web.CurrentUser.ID, web.CurrentUser.LoginName);

listItem["Author"] = oUser;
listItem["Editor"] = oUser;
listItem.Update();
}
}
});
}
}

4 comments:

Jason Apergis said...

Here is an update on the problem I was having with running the update in the web part. Even though I was running under elevated privileges I needed to set AllowUnsafeUpdates = true on the Web. Make sure you set this back to false in a finally block.

Gaurav said...

Thanks a bunch.

Unknown said...

Hi ,
This solution wont work , if u run the code under elevated privilage , Author filed can be updated as oUser , but Editor filed will be updated as system account cos , when code reaches the line ListItem.Update()
the code will run under system account, it means it will be updated as modified by system account

Jason Apergis said...

This is a pretty old thing for me. I recall that for the situation I was in, it gave me the exptected results I needed.

I will take your word for the test you are doing...