Updating Created and Modified information for Files in a SharePoint Document Library
This blog post is about an issue I faced during data import into SharePoint document libraries. I hope it helps others facing the same issue.
Scenario
Documents had to be migrated to SharePoint 2007 document libraries from an existing application along with relevant metadata. In the first stage, documents were exported to a file server and corresponding metadata values were made available in an excel sheet. In the second stage, documents were to be imported into the document libraries.
Problem
I was able to get all the documents into document library along with all metadata except following 4 fields:
- Created (datetime)
- Created By (person)
- Modified (datetime)
- Modified By (person)
Initial Work (actually Initial Search)
I did what most developers do - surf the Internet and search for a "readymade" solution :-)
After a lot of searching and researching, I found most relevant information on Sowmyan Soman's Blog in his post - Can we update the values of "Created By", "Modified By" columns in SharePoint lists ? His solution worked for Lists but not Document Libraries; I don't know the reason yet.
There was also a comment - Remove Read-Only on "Created By", etc. to that post by "Dan". Dan mentioned about removing the ReadOnly="TRUE" attribute from the relevant fields in ONET.XML file. Suggested solution seemed logical but did not work for me.
The Solution
Enter the Microsoft Support team. They resolved the matter in no time by pointing to an existing method available in the SDK!! The solution is using:
SPFileCollection.Add Method (String, Stream, SPUser, SPUser, DateTime, DateTime)
Creates a file in the collection based on the specified URL, on a Stream object that contains a file, on user objects that represent the users who created and last modified the file, and on DateTime values that specify when they did so.
The SDK article also has a code example for copying files in a document library of a Web site to a document library in another Web site. The example preserves the time created and last modified values of the original library. I modified the code to work in my scenario.
Lesson learnt: Read the SDK first and then search on the Internet. For some reason, results from SDK do not end up high in search results on Google or Live. Not sure where the problem lies, with the search engines or with MSDN library.
The Fine Print
The code works when files are being uploaded into a document library. There is no SDK method to update Created and Modified information for exisiting files in a document library.
The Code inside a Try - Catch block
//Get the SharePoint SPSite object
using (SPSite oSite = new SPSite(strSiteURL))
{
//Get the SharePoint SPWeb object
using (SPWeb oWeb = oSite.OpenWeb())
{
//Get the Document library
SPFolder objFolder = oWeb.GetFolder(strDocLibName);
//Get all files in a collection
SPFileCollection objFiles = objFolder.Files;
//Get the SPUser object for createdby user
SPUser userCreatedBy = oWeb.AllUsers[strCreator];
//Get the SPUser object for modifiedby user
SPUser userModifiedBy = oWeb.AllUsers[strModifier];
//Open the file, read its contents and then close it
FileStream mystream = new FileStream(strFilePath, FileMode.Open);
byte[] contents = new byte[mystream.Length];
mystream.Read(contents, 0, (
int)mystream.Length);
mystream.Close();
//Upload the file to library
SPFile file = objFolder.Files.Add(strFiletoUpload, contents, userCreatedBy, userModifiedBy, timeCreated, timeModified);
//Update metadata and also created and last modified datetime again
SPListItem item = file.Item;
item[
"Title"] = strItemTitle;
item[
"Description"] = strItemDescription;
item[
"Created"] = timeCreated;
item[
"Modified"] = timeModified;
file.Item.Update();
}
}
note: variables for which you need to set the value are shown in italics. For actual code, please follow the Best Practices: Using Disposable Windows SharePoint Services Objects too.
Comments
Anonymous
January 01, 2003
You can actually update the author on a document library, but you must update the Author and the Editor fields, and call UpdateOverwriteVersion() on the item. You will most likely want to modifiy the vti_author property too. Assuming $itm is a valid item reference here is some powershell to accomplish the modification- $itm["Author"].tostring() #show current author $itm["Author"] = $oUser #list item author $itm.Properties["vti_author"] = $oUser.User.LoginName #file properties author $itm["Editor"] = $oUser #this needs to be changed as well to update the item. $itm.UpdateOverwriteVersion() $itm["Author"].tostring() #print the changed authorAnonymous
January 01, 2003
Hope you are doing good. We were getting into the same trap too. Hope your solution saves us. I would try and get back. Regards, AviAnonymous
July 30, 2010
Works well! Thanks a lot!Anonymous
October 04, 2010
The comment has been removedAnonymous
March 29, 2012
Hi , how to do the same using moss web service. Any ideas... Thanks in advance,