SharePoint 2010 – Using Document Id to Link to a Specific Version
SharePoint 2010 introduces Document Id, which is an easy way to create document permalinks across a SharePoint Site (SPSite), without worrying about changing names and folders.
This is all nice and well, but what if you’ve enabled versioning, and want to link to a specific version?
It is a shame DocIdRedir.aspx does not accept a version as an optional parameter, but a small shame, as it is easy enough to implement your own handler, using the API method DocumentId.FindUrlById. Alternately, you could have done that yourself and used DocumentId.FindUrlsById, find the appropriate SPListItem and find the version url, if you don’t approve of the way FindUrlById does that for you.
My solution is to create another page, much like DocIdRedir.aspx, and have it accept a version and act accordingly (in this case I’ve created an ASHX handler, but it should be just the same):
public void ProcessRequest(HttpContext context)
{
string docId = context.Request.QueryString["id"];
string versionLabel = context.Request.QueryString["v"];
SPSite currentSite = SPContext.Current.Site;
string url = null;
try
{
url = GetUrlFromID(currentSite, docId, versionLabel);
}
catch (Exception ex)
{
string message = String.Format("Error finding document by id {0} and version [{1}], {2}"
, docId, versionLabel, ex.Message);
SPUtility.TransferToErrorPage(message);
}
if (url == null)
{
string message = String.Format("Could not find document with id {0} and version [{1}]"
, docId, versionLabel);
SPUtility.TransferToErrorPage(message);
}
else
{
context.Response.Write(url);
}
}
private string GetUrlFromID(SPSite site, string docId, string version)
{
//FindUrlById throws an exception if version is empty or null,
// so I check it here to make sure it works.
if (String.IsNullOrEmpty(version))
{
string[] urls = DocumentId.FindUrlsById(site, docId);
return urls.Single(); // think about what you do here
}
else
{
return DocumentId.FindUrlById(site, docId, version);
}
}
After creating and deploying your package, which is effortless in Visual Studio 2010, instead of using the default permalinks:
/_layouts/DocIdRedir.aspx?ID=GROOVY-10-2
you can use your own handler (you may want a shorter solution name and handler):
/_layouts/mySolution/VersionedDocumentId.ashx?id=GROOVY-10-2&v=2.5
See also:
- Source code of FindUrlById
- Source code of the default handler, DocIdRedir.aspx – found in
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\CONFIG\BIN\Microsoft.Office.DocumentManagement.Pages.dll