1

In a SharePoint app i have a custom action in a document library that navigates to an .aspx page. How do I get the full path of a selected document in that .aspx page?

<CommandUIHandlers>
        <CommandUIHandler Command="Invoke_RibbonCustomAction1ButtonRequest"
                          CommandAction="~remoteAppUrl/Pages/CustomActionTarget.aspx?HostUrl={HostUrl}&amp;Source={Source}&amp;ListURLDir={ListUrlDir}&amp;SelectedListID={SelectedListId}&amp;SelectedItemID={SelectedItemId}"/>
      </CommandUIHandlers>

With this code I can get the path of the document library (Source) and the ID of the selected document (SelectedItemId) but I want the path to the document itself.

1

According to this MSDN page, there is no such token available:

The following tokens are recognized:

  • {ItemId} – ID (GUID) taken from the list view.
  • {ItemUrl} – Web-relative URL of the list item (Url).
  • {RecurrenceId} – ID of a recurrent item (RecurrenceID).
  • {SiteUrl} – The fully qualified URL to the site (Url).
  • {ListId} – ID (GUID) of the list (ID).
  • {ListUrlDir} – Server-relative URL of the site plus the list's folder.
  • {Source} – Fully qualified request URL.
  • {SelectedListId} – ID (GUID) of the list that is currently selected from a list view.
  • {SelectedItemId} – ID of the item that is currently selected from the list view.

Since there is no such token, and JS is not allowed in remote ribbon customizations due to security reasons, you have to use additional code to determine the document's URL once the user arrived to your page.

This involves an additional query to the server, yes - thus it is likely that there will be a small delay because of this. Unfortunately, there doesn't seem to be any way to avoid this additional query :(

The code is, however, very simple. Something like this from C# (not tested):

var hostUrl = HttpContext.Current.Request.QueryString["HostUrl"];
var listId = new Guid(HttpContext.Current.Request.QueryString["SelectedListID"]);
var listItemId = Convert.ToInt32(HttpContext.Current.Request.QueryString["SelectedItemID"]);

ClientContext context = // get client context with access token for the specified host url

List list = context.Web.Lists.GetById(listId); 
ListItem item = list.GetItemById(listItemId); 

context.Load(item); 
context.ExecuteQuery(); 

var serverRelativeDocumentUrl = (string)item["FileRef"];

or from JS (tested):

var hostweburl = GetUrlKeyValue("HostUrl");
var listId = GetUrlKeyValue("SelectedListID");
var itemId = GetUrlKeyValue("SelectedItemID");

var context = SP.ClientContext.get_current();
var hostContext = new SP.AppContextSite(context, hostweburl);

var list = hostContext.get_web().get_lists().getById(listId);
var listItem = list.getItemById(itemId);
context.load(listItem);
context.executeQueryAsync(function() 
{
  // returns '/sites/developer/Shared Documents/123.docx' for me
  // ('/sites/developer' is the host web server relative url)
  var serverRelativeDocumentUrl = listItem.get_item("FileRef");
},
function(sender,args) {
  alert('ERR:  ' + args.get_message())
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.