Sometime we may require to see a different versions of a document in the Document Library. By Out Of The Box, you can view the properties, version history etc., But if you want to see exactly the content of a specific version, then you need to Restore it. There is no option that I could see. Probably if am wrong, and if there is a possibility to view that, please share to the community. In that case, let us see, how we are going to achieve the same using C# server side object model.
Moreover the actual requirement was like this. I was in an urge to write a timer, which needs to get the documents from the source document library and upload the same to the Destination Document Library. The key here, is the document needs to be uploaded along with the versions and the version properties like Created User, Modified User, Created Time, Modified Time etc.,
With this requirement, let us jump into the code. As all of us aware that, before creating a timer job, let us create our methods on a console application. Because that would be very much easy for us to debug and run. This will increase our coding speed also. Once, the method is perfect, we can copy and paste the same into a timer job solution. With this in mind, let us create a Console Application. As a first step, we need to fetch the document from the Source Document Library along with the Version.
Our Console Application will looks like
static void Main(string[] args)
{
try
{
//The Source Site collection
string strSourceSiteURL = "https://sathishserver.ss.loc:20004/sites/DeveloperSite/";
//Destination Site collection
string strSourceDocumentLibrary = "SourceDocumentLibrary";
//Creating an instance of the Site
using (SPSite oSite = new SPSite(strSourceSiteURL))
{
//Getting the instance of the Web
using (SPWeb oWeb = oSite.OpenWeb())
{
//Navigating to the Document Library
SPList oList = oWeb.Lists[strSourceDocumentLibrary];
//Get all List Items.
SPListItemCollection oListItems = oList.Items;
//Iterate through the list items.
foreach (SPListItem oItem in oListItems)
{
byte[] byteFile;
// Here assuming the List as a document library. Hence the Items would be File only.
SPFile file = oItem.File;
SPUser LastModifiedUser = null;
//Validating the File
if (file != null)
{
//Reading the file Content.
byteFile = file.OpenBinary();
string strFileName = file.Name;
//Get the Versions of the File
SPFileVersionCollection versions = file.Versions;
//Iterating through the versions
foreach (SPFileVersion version in versions)
{
//Here dont upload the current Version. This I will explain on the Article
if (!version.IsCurrentVersion)
{
Upload(version);
}
else
{
//LastModifiedUser = version.CreatedBy;
}
}
LastModifiedUser = file.ModifiedBy;
Upload(file,LastModifiedUser);
}
}
}
}
}
catch (Exception ex)
{
}
}
The code is Self Commented. The only place we need to concentrate is I have a method Upload, which has 2 overloads. One is with the Version and the other one is file. Because, the SPFileVersionCollection object will not fetch the current unpublished version. Hence, if the last version which is being checked in is not published, then our code will miss that version. To avoid that, we are uploading the file as it is once all the versions were uploaded. Then we may have a query that, why we are checking for the IsCurrentVersion. if (!version.IsCurrentVersion)
We are doing that because, to avoid the challenge in the published documents. For example, if a latest checked in document is published, then our iteration will also upload and the last Upload(file, lastmodifiedUser) will also upload the same document. Hence there will be a version increase.
Now, let us see how to upload the same in to the document library. This is a simple straight forward one.
public static void Upload(SPFileVersion version)
{
try
{
string strDestinationSiteURL = "http://sathishserver:20000/sites/VHS/";
string strDestinationDocumentLibrary = "DestinationDocumentLibrary";
//modifiedUser.UserToken
using (SPSite oSite = new SPSite(strDestinationSiteURL, version.CreatedBy.UserToken))
{
using (SPWeb oWeb = oSite.OpenWeb())
{
SPFolder libFolder = oWeb.Folders[strDestinationDocumentLibrary];
SPUser FileCreatedBy = oWeb.EnsureUser(version.File.Author.LoginName);
SPUser FileCheckinUser = oWeb.EnsureUser(version.CreatedBy.LoginName);
if (!FileExists(libFolder, version))
{
SPFile spfile = libFolder.Files.Add(version.File.Name, version.OpenBinary(), FileCreatedBy, FileCheckinUser, version.File.TimeCreated, version.Created);
//spfile.Update();
}
else
{
if (libFolder.RequiresCheckout)
{
SPFile fileOld = libFolder.Files[version.File.Name];
fileOld.CheckOut();
SPFile spfile = libFolder.Files.Add(version.File.Name, version.OpenBinary(), FileCreatedBy, FileCheckinUser, version.File.TimeCreated, version.Created);
//spfile.Update();
spfile.CheckIn("Upload Comment", SPCheckinType.MajorCheckIn);
spfile.Publish("Publish Comment");
}
}
libFolder.Update();
}
}
}
catch (Exception ex)
{
}
}
public static void Upload(SPFile file,SPUser LastModifiedUser)
{
try
{
string strDestinationSiteURL = "http://sathishserver:20000/sites/VHS/";
string strDestinationDocumentLibrary = "DestinationDocumentLibrary";
//modifiedUser.UserToken
using (SPSite oSite = new SPSite(strDestinationSiteURL,LastModifiedUser.UserToken))
{
using (SPWeb oWeb = oSite.OpenWeb())
{
SPFolder libFolder = oWeb.Folders[strDestinationDocumentLibrary];
SPUser FileCreatedBy = oWeb.EnsureUser(file.Author.LoginName);
SPUser FileCheckinUser = oWeb.EnsureUser(file.ModifiedBy.LoginName);
if (!FileExists(libFolder, file.Name))
{
SPFile spfile = libFolder.Files.Add(file.Name, file.OpenBinary(), FileCreatedBy, FileCheckinUser, file.TimeCreated, file.TimeLastModified);
//spfile.Update();
}
else
{
if (libFolder.RequiresCheckout)
{
SPFile fileOld = libFolder.Files[file.Name];
fileOld.CheckOut();
SPFile spfile = libFolder.Files.Add(file.Name, file.OpenBinary(), FileCreatedBy, FileCheckinUser, file.TimeCreated, file.TimeLastModified);
//spfile.Update();
spfile.CheckIn("Upload Comment", SPCheckinType.MajorCheckIn);
spfile.Publish("Publish Comment");
}
}
libFolder.Update();
}
}
}
catch (Exception ex)
{
}
}
With this, the documents will get uploaded into the Destination Document Library along with the modified user and the remaining properties also.
The key point here if you noticed is while creating the Site Object.
using (SPSite oSite = new SPSite(strDestinationSiteURL,LastModifiedUser.UserToken))
Instead of giving only the URL, here we are giving the UserToken of the Modified User also. Though we are updating the modified user, created user properties while uploading, SP is taking the user context of the Site. To overcome that, I created the Site Object itself with the context of Modified User. Now, The document is getting uploaded with the Name of the modified user.
Basically, we are trying to Impersonate the Context of the Site with the Modified User property. That’s it. Hope this one is very straight forward and helped you. Thanks.
Souce Code Can be downloaded from Here.
Happy Cooding.
Sathish Nadarajan.
Leave a comment