I am attempting to create a new document in an ItemCheckingOut event receiver, replacing the existing stub document with a new document containing current content downloaded from an external system. I need to preserve the document author and editor
from the original document. The document is created successfully, and running with elevated privileges allows the creation and modification dates to be set.
By sandwiching the SPFileCollection.Add call between logging statements, I can see the passed parameters and the result.
Restoring file: folder.Files.Add(Shared Documents/Off2010 Excel2.xlsx, [], "i:0#.w|vdcqa\cbrown", "i:0#.w|vdcqa\dgreenland", 02/28/2013 13:33:19, 02/28/2013 13:35:03)
Restored file: SPFile.TimeCreated='02/28/2013 05:33:19', SPFile.Author='SHAREPOINT\system', SPFile.TimeLastModified='02/28/2013 05:35:03', SPFile.ModifiedBy='SHAREPOINT\system'
The TimeCreated and TimeLastModified properties are set to the expected values, but the Author and ModifiedBy are not set. This works in SP2010 so I suspect the issue may be related to the claims based authentication as the SPUser objects passed as
input have claims based authentication prefixes, but I don't see how to pass the SPUser properties in a way that will work in this case.
public override void ItemCheckingOut(SPItemEventProperties properties)
{
SPListItem item = properties.ListItem;
string fileName = GetFileNameFromLinkName(item.Name);
byte[] data = GetFileContents(item);
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite elevatedSite = new SPSite(properties.WebUrl))
{
elevatedSite.AllowUnsafeUpdates = true;
using (SPWeb elevatedWeb = elevatedSite.OpenWeb())
{
elevatedWeb.AllowUnsafeUpdates = true;
SPListItem linkItem = elevatedWeb.Lists[properties.ListId].GetItemById(properties.ListItem.ID);
try
{
fileName = GetUniqueFileName(fileName, linkItem.Url, elevatedWeb);
SPFolder folder = linkItem.File.ParentFolder;
DateTime timeCreated = Convert.ToDateTime(linkItem["Created"]); }
DateTime timeLastModified = Convert.ToDateTime(linkItem["Modified"]); }
SPUser createdBy = null;
object authorPropVal = linkItem["Author"];
if (authorPropVal != null)
{
SPFieldUserValue uv = new SPFieldUserValue(elevatedWeb, authorPropVal.ToString());
if (uv != null)
createdBy = uv.User;
}
SPUser modifiedBy = null;
object editorPropVal = linkItem["Editor"];
if (editorPropVal != null)
{
SPFieldUserValue uv = new SPFieldUserValue(elevatedWeb, editorPropVal.ToString());
if (uv != null)
modifiedBy = uv.User;
}
Log.Trace("Restoring file: folder.Files.Add({0}/{1}, [], \"{2}\", \"{3}\", {4}, {5}",
folder.Url, fileName, createdBy, modifiedBy, timeCreated, timeLastModified);
SPFile newItem = folder.Files.Add(
folder.Url + "/" + fileName,
data,
createdBy,
modifiedBy,
timeCreated,
timeLastModified);
SPTimeZone timeZone = elevatedWeb.RegionalSettings.TimeZone;
Log.Trace("Restored file: SPFile.TimeCreated='{0}', SPFile.Author='{1}', SPFile.TimeLastModified='{2}', SPFile.ModifiedBy='{3}'",
timeZone.UTCToLocalTime(newItem.TimeCreated),
newItem.Author,
timeZone.UTCToLocalTime(newItem.TimeLastModified),
newItem.ModifiedBy);
}
catch (Exception ex)
{
Log.Error(ex, "Failure creating content item for file: {0}", fileName);
throw;
}
}
}
});
}
Can anyone help me understand what is going on and suggest a way to fix it?
Dave M