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.
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.
I was able to get all the documents into document library along with all metadata except following 4 fields:
Created By (person)
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.
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);
//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;
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.