40

SharePoint 2013 CSOM API contains the following methods for accessing List object:

For example:

var listTitle = "Tasks";
using(var ctx = new ClientContext(webUrl))
{
     var list = ctx.Web.Lists.GetByTitle(listTitle);
     ctx.Load(list);
     ctx.ExecuteQuery();
}

From another hand, SSOM API contains SPWeb.GetList method to gets the list that is associated with the specified server-relative URL.

The question is: how to effectively load List by server-relative URL in CSOM?

2
  • 1
    Vadim, if you had mention using another method other than CSOM, then yes. The SOAP services has it a method that you can use - SiteData.GetURLSegments. I wrote about it here: paultavares.wordpress.com/2014/02/18/…
    – Paul T.
    Commented Sep 30, 2014 at 19:19
  • ListCollection lists = context.Web.Lists; context.Load(lists, all => all.Include(l => l.RootFolder)); It does not work either!
    – ananda
    Commented May 27, 2017 at 8:05

5 Answers 5

30

This seems to be pretty close in performance:

context.Load(lists, all => all
  .Where(l => l.RootFolder.Name == "MyListUrl")
  .Include(l => l.Id));
context.ExecuteQuery();
list = lists.Single();

If you need to get this by server-relative url you would need to parse the web url and list url first.

3
  • 1
    Had to take some performance tests away from the answer because of high variance. Anyways there doesn't seem to be big difference in performance (~0-25%).
    – thomius
    Commented Sep 30, 2014 at 13:16
  • 1
    Cool, also added an extension method here: Not so pretty with all the parsing..
    – thomius
    Commented Sep 30, 2014 at 15:03
  • Took the extension method away because didn't invent how to protect against user giving a subfolder as an argument (instead of the actual list/library RootfolderName), without executing query more than once.
    – thomius
    Commented Sep 30, 2014 at 15:38
35

For those who are still looking for the answer. SharePoint 2013 (since SP1 at least see UPD below) contains special method Web.GetList. It accepts site-relative url for the list, i.e. site/dev/lists/mylist.

Sample code for .NET object model:

var ctx = new ClientContext("http://sp2013dev/sites/dev");
var list = ctx.Web.GetList("sites/dev/lists/Addresses");
ctx.Load(list);
ctx.ExecuteQuery();    
Console.WriteLine(list.Title);

The same situation for JavaScript object model (except the fact that msdn documentation is lacking and you don't find this method here at the moment of writing this, May 2015):

var context = SP.ClientContext.get_current();
var list = context.get_web().getList("/sites/dev/Lists/Addresses"); 
context.load(list);
context.executeQueryAsync(function() { 
    alert("loaded!"); 
    }, function() { 
    alert("failed!"); 
});

Now we don't need all this hacks with folder or list properties.

UPD:

Just tested that this method is not included in SP1. It works starting from February 2015 CU (sorry, can't check the exact CU number)

5
  • Oh, finally, i suppose it should be considered as the most accurate answer then.Thanks! Commented May 6, 2015 at 13:05
  • I couldn't find this method in the latest NuGet download of the DLL. Instead, I found an version of the DLL on my dev server (patched to March 2015 CU) but it didn't work for Production which is only SP1.
    – PeterX
    Commented May 14, 2015 at 4:51
  • @PeterX, you're correct, unfortunately SP1 doesn't contain this method, I've already mentioned it. It seems it was included at the end of 2014 or at the beginning of 2015. Commented May 14, 2015 at 8:37
  • I can confirm that it also works with absolute urls
    – Kirschi
    Commented Aug 10, 2016 at 8:32
  • 3
    And as it's included in the CSOM, now the REST endpoint are also updated: _api/web/getList('/sites/yoursite/yourlibraryOrList')
    – dbardakov
    Commented Jan 26, 2017 at 12:12
19

Yet another version to load List by server relative Url using CSOM.

The solution consists of the following steps:

  1. Retrieve list Folder object using Web.GetFolderByServerRelativeUrl method
  2. Retrieve List by specifying List ID stored in vti_listname property from Folder.Properties object

Code:

static class WebExtensions
{
    /// <summary>
    /// Load List by server relative Url
    /// </summary>
    /// <param name="web"></param>
    /// <param name="listUrl"></param>
    /// <returns></returns>
    public static List LoadListByUrl(this Web web, string listUrl)
    {
        var ctx = web.Context;
        var listFolder = web.GetFolderByServerRelativeUrl(listUrl);
        ctx.Load(listFolder.Properties);
        ctx.ExecuteQuery();
        var listId = new Guid(listFolder.Properties["vti_listname"].ToString());
        var list = web.Lists.GetById(listId);
        ctx.Load(list);
        ctx.ExecuteQuery();
        return list;
    }
}

Usage

using(var ctx = new ClientContext(webUrl))
{
    ctx.Credentials = new SharePointOnlineCredentials(userName,securePassword);
    var tasksList = ctx.Web.LoadListByUrl("Lists/Tasks");
    Console.WriteLine(tasksList.Title);
}

Cons:

  1. Only SharePoint 2013 CSOM is supported
  2. Requires two separate requests to server
6
  • 1
    Nice usage of out-of-the-box methods, and no need to parse server-relative url.
    – thomius
    Commented Sep 30, 2014 at 15:06
  • 1
    Also you can use rest api to get list id instead of relying on property bags: http://sharepoint/_api/web/lists/?$expand=RootFolder&$filter=RootFolder/ServerRelativeUrl eq '/Lists/MyCoolList'&$select=ID. It also should reduce client-server traffic Commented Mar 19, 2015 at 10:55
  • I get the error Error 2 'Microsoft.SharePoint.Client.Folder' does not contain a definition for 'Properties' and no extension method 'Properties' accepting a first argument of type 'Microsoft.SharePoint.Client.Folder' could be found (are you missing a using directive or an assembly reference?) any thoughts?
    – PeterX
    Commented May 14, 2015 at 4:06
  • 1
    I now get a ServerException / File Not Found. error, using either an absolute URL or a relative URL.
    – PeterX
    Commented May 14, 2015 at 4:36
  • 1
    @PeterX, if you have site/test url for site collection, then you rest query should be: http://sharepoint/sites/test/_api/web/lists/?$expand=RootFolder&$filter=RootFolder/ServerRelativeUrl eq '/sites/test/Lists/TestList'&$select=ID. Just copy paste it into the browser (with valid sharepoint and list urls) and will see the result. Commented May 14, 2015 at 8:34
2

I unfortunately couldn't get any of the above working, so I used an ugly hack:

public static List GetListByUrl(ClientContext context, string listUrl)
        {
            List result = null;

            ListCollection lists = context.Web.Lists;
            context.Load(lists, all => all.Include(l => l.RootFolder));            
            context.ExecuteQuery();

            string listUrlPartial = new Uri(listUrl).PathAndQuery.ToLower().Replace("%20", " ");
            foreach (List list in lists)
            {
                string thisListUrlPartial = list.RootFolder.ServerRelativeUrl.ToLower().Replace("%20", " ");
                if (listUrlPartial.StartsWith(thisListUrlPartial))
                {
                    result = list;
                    break;
                }
            }

            return result;
        }

Of course, your mileage will vary. Recommend upgrading to latest SharePoint patch to get the new method (as per @Kai's answer), but unfortunately I don't have that option at the moment.

0

I do not have SP1 for my SharePoint, but this worked for me:

var clientContext = new SP.ClientContext("absolute url to sites that contains the list");

var IssueList = clientContext.get_web().get_lists().getByTitle("title of the list");

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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