Find SPList by using the internal name

SPList instance = web.Lists["MyCustomList"];

Recognize this little piece of code? I don´t know how many times I have written code like that. What´s the problem with it then? Well, it uses the display name of the list to find it.
What if I have a list name like “Custom Lists – Orders that have been deleted” (ok, bad example but anyway). Annoying to write that code and what if I change the displayname.
What I´m setting out to do is to find a method to find the list by its internal name instead.
I´m going with an extension method approach so imagine that this code resides in a static class called SPWebExtensions.

The try / catch solution


public static SPList FindListByName(this SPWeb web, string listname)
{
SPList list = null;
var relativeUrl = web.ServerRelativeUrl.Equals("/") ? string.Empty : web.ServerRelativeUrl;

try
{
list = web.GetList(string.Concat(relativeUrl, "/Lists/", listname));
}
catch
{
list = web.GetList(string.Concat(relativeUrl, "/", listname));
}

return list;
}

The list will either be in /Lists/[name] or /[name] depending whether or not it´s a doc lib or not.
Ok, so what´s wrong with this picture? Anyone?
First of all it´s bad design to use try /catch like this and secondly a try / catch will definitely impact on performance.  No, skipping that.

The RootFolder solution


public static SPList FindListByName(this SPWeb web, string listname)
{
// RootFolder == internal listname, loop through and find (null will be returned if its not found)
var list = (from SPList l in web.Lists
where l.RootFolder.listname.Equals(listname, StringComparison.InvariantCulture)
select l).FirstOrDefault();

if (list == null)
{
throw new FileNotFoundException(string.Format(
"SPList '{0}' not found on web '{1}'", listname, web.Url));

}
return list;

}

A colleague of mine (Thomas Persson) pointed out that the RootFolder is always equivalent to the internal name of the list. Great, so I will use Linq to get the list where the rootfolder corresponds to the name I´m looking for.
This solution works but I will try to optimize it a bit.

The RootFolder solution final version

public static SPList FindListByName(this SPWeb web, string name)
{
SPList instance = null;

string key = name;

if (web.Properties.ContainsKey(key))
{
try
{
instance = web.Lists[new Guid(web.Properties[key])];
}
catch
{
web.Properties[key] = null;
web.Properties.Update();

return FindListByName(web, name);
}
}
else
{
// RootFolder == internal name, loop through and find (null will be returned if its not found)
instance = (from SPList list in web.Lists
where list.RootFolder.Name.Equals(name, StringComparison.InvariantCulture)
select list).FirstOrDefault();

if (instance != null)
{
web.Properties.Add(key, instance.ID.ToString("B"));
web.Properties.Update();
}

}

return instance;
}

Same sort of code but here I´m using the web.Properties to store store the ID of the list so that I don´t have to go through all the lists at every time. As soon as I find the list I will “cache” the id.

usage:
SPList instance = web.FindListByName(“MyCustomList”);

UPDATE 2010-02-20: The code for the extension method can now found on codeplex.

,

  1. #1 by mcdonalds coupons on September 14, 2009 - 01:07

    Thanks much for that informational blog post.

  2. #2 by Örjan Sternemo on November 16, 2009 - 01:11

    Thank you very much for a great blog post. I'm using promotion/demotion in a project of mine and it works perfectly! So thanks a lot! While testing though I saw an error that had to correct on line 15 in the FindListByName method:
    


    web.Properties[key] = null;

    Actually that does not turn the properties.ContainsKey(key) to false in our case, leaving us with an infinite loop than normally ends with a stackoverflow and no action. What I did instead was to simply remove the key:


    web.Properties.Remove(key);

    I think that was probably your intention right?
    
    Brgds,
    Örjan
    
    • #3 by Johan Leino on November 16, 2009 - 10:24

      Thanks for the feedback Örjan. My intention was exactly that (removing the key) but from other bloggers out there I got the impression that the remove method didn´t work as expected so the workaround was to null it. They/I probably got it wrong or maybe MS fixed whatever issue was up with the remove method. Anyhow, great that u got it working.

  3. #4 by Rico Piccoli on February 25, 2010 - 18:34

    Though I would’ve loved it much more if you added a relevant video or at least pictures to back up the explanation, I still thought that your write-up quite helpful. It’s usually hard to make a complicated matter seem very easy. I enjoy your weblog and will sign up to your feed so I will not miss anything. Fantastic content

  4. #5 by viktorstelle on September 15, 2011 - 21:44

    Thanks for the provided solution. I have additional question about using SPWeb.Properties.Update() method. Wouldn’t this cause save conflict when multiple users will simultaneously update web property with the same key?

    • #6 by Johan Leino on September 16, 2011 - 07:49

      could very well be a possible bottleneck yes. I’m sure that there’s other, better, solutions. Maybe looking into PnP SP Guidance for better save conflict handling. They have support for adding any object to the property bag, thus you could use hashtable or a thread-safe dictionary that can probably handle conflict scenarios

  5. #7 by Divyesh on February 19, 2016 - 12:46

    Nice post..

    Just for sharing I have found below also helpful for same scenario:

    public static bool InspectForList(string listName)
    {
    var results = SPContext.Current.Web.Lists.Cast().Where(item => Equals(string.Compare(item.RootFolder.Name, listName, true), 0));
    return results.Count() > 0;
    }

    Cheers…

  1. GetList by internal name | AreBelongBlog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: