03 Dec 2012

Handling SharePoint file versions programmatically

Paul Ryan

In my recent project, I had  to link to and download specific versions of documents stored in SharePoint. In this blog, I want to highlight some aspects that  SharePoint users should be aware of when performing a similar task.

beware of Different version collections!

The first thing to be aware of is that there are two distinct version collections: SPFileVersionCollection and SPListItemVersionCollection. These collections can be accessed via the respective assets as you would expect (SPFile.Versions and SPListItem.Versions) and, as is the way in SharePoint, are enumerations of SPFileVersion and SPListItemVersion objects, respectively. These objects, which represent the individual versions, have a number of similar properties and methods but do not share a base class nor an interface.

how to access specific versions of documents

In order to access specific versions of documents, the approach I took was to store the VersionLabel (a property on both SPFileVersion and SPListItemVersion) and then retrieve the version by using this value in conjunction with GetVersionFromLabel (a method on both SPFileVersion and SPListItemVersion). This works but with a number of caveats:

    1. SPFileVersionCollection does NOT contain an entry for the latest version

      This means that if the document has only a single version then this collection will be empty. If you want to access the latest version you must verify that the version label refers to the latest version by comparing it to the first entry in the SPListItemVersionCollection and if it is then access the SPFile directly. If you are accessing properties that are also present on an SPListItemVersion (i.e. not opening a stream) you can use that collection instead but you must also take note of the next point

    2. Expect SPListItemVersion.Url behaves unexpectedly in some situations

      Pressumably, this is to support directing underprivileged users away from minor versions that they are not allowed to see (although I don’t see how it achieves this), the Urlfor minor versions will be equal to that of the latest minor version when there is no published version. Always use SPFileVersion.Url

    3. Minor versions get promoted when published, breaking links to the minor version

      For example: you have a document currently at version 0.2, with a previous 0.1 version. When you publish this document you still only have two versions: 0.1 and 1.0. You will now fail to locate version 0.2. Don't be fooled into thinking that using the VersionId property will solve this issue. It simply represents the the version label as an integer (+1 for each minor version, +512 for each major version).

      The only way I could find to handle this case is to introduce the doc store version which is stored in the property bag of the SPFile: SPFile.Properties["vti_docstoreversion"]. You can see how this works by looking at the code examples I have included below. This is a cleaner version of the code (see here for an extended code). Also note that the doc store version is only stored in the SPFile property bag and not in the SPListItem property bag.




Have you got any project experience with SharePoint you would like to share? Join the discussion 


Paul Ryan

About the author

As a developer with Concentra my professional interests are technical and tend to be SharePoint focused. Expect to read gotchas, how-tos and about up-and-coming tech. I've been working with SharePoint for over 4 years and hope my posts will give back a little to the community that's supported me over this time. I'm also a keen runner (half-marathon) and passionate Brompton owner.