SharePoint – Creating a document URL handler – dynamic and static
I wrote a post about adding the built in document id to the document file name. Now I will show you another way to use the built in document id when referring to the documents.
Lets say we are in a big project with several baselines . And every baseline requires it’s own version of a document, but the same document. It could be that new requirements have been added along the way or maybe the architecture has changed from one to another. This might cause the document name to change for some reason and that will break the link from a previous baseline.
What if you had a link that:
- Will never break as long as the document or version is not deleted.
- Can point to the current version.
- Can point to a specific version.
- Can point to the latest major version.
Lets say that link would look something like this
Latest version -> Dynamic
http://SharePoint.home.local/_layouts/customapplicationpages/getdocbyid.aspx?docid=TESTID-1-12
Specific version -> Static, kind of
http://SharePoint.home.local/_layouts/customapplicationpages/getdocbyid.aspx?docid=TESTID-1-12&version=1.2
Latest major version -> Dynamic
http://SharePoint.home.local/_layouts/customapplicationpages/getdocbyid.aspx?docid=TESTID-1-12&version=major
Microsoft has provided some great functions from the Office API that we can use when we search for the document via the document id.
Creating the application page – URL handler
First of we need to create an application page that can handle the query-strings from the URL. This can be done quite easy, just map the SharePoint layouts folder to you project (I also added a new folder called customapplicationpages) and add an Application Page. In our case I added a page called getdocbyid.aspx. We don’t have to create any markup for this application page, just code behind. So basically, what we need to do is capture the id and the version and find the right document and redirect to the URL. This is how I implemented it, note that the current version of a document is not a part of the document version history.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
public partial class GetDocById : LayoutsPageBase { protected void Page_Load(object sender, EventArgs e) { string docId = Request.QueryString["docid"]; if (docId != null) { string versionLabel = Request.QueryString["version"]; try { //Find the Url to the version. string url = GetUrlFromID(docId, versionLabel); if (!string.IsNullOrEmpty(url)) { //Redrirect to the version Url. Response.Redirect(url); } } catch { SPUtility.TransferToErrorPage("The document ID or version does not exists"); } } SPUtility.TransferToErrorPage("No version was found"); } private string GetUrlFromID(string docId, string version) { //Get the urls found with the document id. string[] urls = DocumentId.FindUrlsById(SPContext.Current.Site, docId); if (urls.Any()) { var url = urls.First(); //Return first URL if no version is specified. if (string.IsNullOrEmpty(version)) { return url; } //If version is specified, web need to find that version url. else { SPFile file = SPContext.Current.Web.GetFile(url); //Since the current version is not a part of the version history //it will be returned if match with specified version. if (file.UIVersionLabel == version) { return file.ServerRelativeUrl; } //If it is the current major version. if (version.Equals("major", StringComparison.CurrentCultureIgnoreCase)) { version = string.Format("{0}.0", file.MajorVersion); //Since the current version is not a part of the version history //it will be returned if match with specified major version. if (file.UIVersionLabel == version) { return file.ServerRelativeUrl; } } //Return the version based on the spcified version return string.Format("{0}/{1}", SPContext.Current.Web.Url, file.Versions.GetVersionFromLabel(version).Url); } } //Return the document by id and version. return DocumentId.FindUrlById(SPContext.Current.Site, docId, version); } } |
From this code we can see that we use tow different method when getting the document. FindUrlsById is used first because FindUrlById requires a version parameter which will not include the current version.
The URL isn’t that pretty, especially with the _layouts and application folder. There are several ways to make it look better, I prefer a solution where you don’t have to call a page in the URL. You can do this the hard way by creating a new redirect website in the IIS or you can do like I did and create a subsite called getdocument with only one purpose, redirect to the application page, You can redirect via JavaScript or server, I will leave that to you. But the outcome will be a new URL which that would look like this.
Latest version
http://SharePoint.home.local/getdocument?docid=TESTID-1-12
Specific version
http://SharePoint.home.local/getdocument?docid=TESTID-1-12&version=1.2
Latest major version
http://SharePoint.home.local/getdocument?docid=TESTID-1-12&version=major
If you check out this post, you will find a way to build the URL’s via the SharePoint GUI.