sharepointdesign-patternsnullreferenceexceptionsplist

SPList instance members throw a NullReferenceException


To cut a long story real short... I have a class (in my sample scenario it's a application page) which holds a reference to a SPList.

public partial class ApplicationPage1 : LayoutsPageBase
{
    private static SPList _list = GetSPList();

    private static SPList GetSPList()
    {
        try
        {
            return SPContext.Current.Web.GetList("/Lists/CoreConfiguration");
        }
        catch (FileNotFoundException)
        {
            return null;
        }
    }

    protected void BtnRunQuery_OnClick(object sender, EventArgs e)
    {
        Debug.WriteLine(_list.Author.Name);
    }
}

The interesting part is the button click event obviously. Because the first time it always works. And maybe if you are lucky it works a 2nd or a 3rd time. But it almost never works a 4th time at which point it throws a NullReferenceException. It's not the list itself which throws the exception but rather some members of the class. Obviously the SPList object is more dead than alive.

So apparently it's not a good idea to hold a reference to a SPList. Is the design pattern to follow here to go and get the list each and every time? On each request?


Solution

  • No, it's not the very best idea to hold an SPList instance in a static field. In fact, you may not do that. As SPContext.Current's name indicates, it the current context in the very specific point in time. To put it short (and simplified), it's request-specific, and a SPList instance is as well.

    You have to retrieve a new SPList instance every time you need it. Internally, it's bound to SPWeb instance, for which it's the same—it cannot survive among requests. The rule of thumb here is: how would you distinguish among different users' permission should you have just one static SPList instance?


    Side note: The reason why it worked for the 1st request is plain simple: You class gets initialized by the CLR when it's first used, which is apparently during the first request. The CRL then invokes the class'es static constructor, which computes values of static members, and since SPContext.Current is valid at that time, it seams to work.