We have a web part that uploads a document to a document library. The user uploading the document may not have access to the destination location, so the code adding the file executes within a RunWithElevatedPrivileges block. This means the "Modified By" field is always set to System Account. Here is the code:
SPSecurity.RunWithElevatedPrivileges(
delegate
{
using (SPSite elevatedSite = new SPSite(SPContext.Current.Site.Url))
using (SPWeb targetWeb = elevatedSite.OpenWeb(webUrl))
{
targetWeb.AllowUnsafeUpdates = true;
SPFile newFile = files.Add(filename, file);
SPListItem item = newFile.Item;
// TODO: Insert code to set Modified By
item.SystemUpdate();
}
}
}
The "Modified By" field needs to be set to the name of the current user (at the TODO line above), but none of the following attempts have worked:
item["Modified By"] = SPContext.Current.Web.CurrentUser;
item["Author"] = SPContext.Current.Web.CurrentUser;
item["Modified By"] = new SPFieldUserValue(
SPContext.Current.Web, SPContext.Current.Web.CurrentUser.ID,
SPContext.Current.Web.CurrentUser.Name);
item["Author"] = new SPFieldUserValue(
SPContext.Current.Web, SPContext.Current.Web.CurrentUser.ID,
SPContext.Current.Web.CurrentUser.Name);
Does anyone know of a solution that allows the "Modified By" value to be changed?
I did some more testing...
item["Editor"] = SPContext.Current.Web.CurrentUser;
item["Author"] = SPContext.Current.Web.CurrentUser;
item.SystemUpdate();
Created By is set to the current user but Modified By is set to System Account.
item["Editor"] = SPContext.Current.Web.CurrentUser;
item["Author"] = SPContext.Current.Web.CurrentUser;
item.Update();
Both Created By and Modified By are set to the current user.
The problem was using SPListItem.SystemUpdate() which does the exact opposite of what the API documentation states, at least when running with elevated privileges.
Note: SPContext.Current.Web.CurrentUser does pick up the current user and not the system account when running within SPSecurity.RunWithElevatedPrivileges. (Whether it should be used like this is another question.)
One way to solve this is by storing the currently logged user in memory before elevating permissions. Later in the update request, replace the 'System account' with with your variable.
See below:
// Keep a reference of the Logged in user in memory
SPUser currentUser = SPContext.Current.Web.CurrentUser;
SPSecurity.RunWithElevatedPrivileges(
delegate
{
using (SPSite elevatedSite = new SPSite(SPContext.Current.Site.Url))
using (SPWeb targetWeb = elevatedSite.OpenWeb(webUrl))
{
targetWeb.AllowUnsafeUpdates = true;
SPFile newFile = files.Add(filename, file);
SPListItem item = newFile.Item;
// Replace 'System Account' with current user
item["Author"] = currentUser;
item["Modified By"] = currentUser;
item.SystemUpdate();
}
});
I hope this helps.
Do as (Henrique Zacchi) writes, but build a wrapper extension method that takes in SPUser as an additional param. Then use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With