Saturday, April 3, 2010

"Object reference not set to an instance of an object" when using HttpContext.Current.Cache in an ASP.NET Custom Web Server Control

Recently I was developing a custom ASP.NET Web Server Control, and I was making use of the Cache to read data only once, and not after every PostBack.

But when I then tried to view the Control in the Design View of an ASP.NET page, I got the following:


I then traced the problem to the following Property I had in my Control:

public IEnumerable<provider> Providers
{
    get
    {
        if (HttpContext.Current.Cache[ProjectSettings.CacheKey] == null) //This line was throwing the exception
        {
            return null;
        }
        return (IEnumerable<provider>)HttpContext.Current.Cache[ProjectSettings.CacheKey];
    }
}

The Object reference not set to an instance of an object exception was being thrown because I was trying to access a key from the Cache when the Cache was null. This is because when the website is not running, the HttpContext.Current will not be available and thus be set to null.

Fixing the problem


Therefore, to cater for this problem with the Design View rendering, I made use of such a "hack":

public IEnumerable<provider> Providers
{
    get
    {
        /*
         * Begin Hack:  The following [if (HttpContext.Current == null)] is used because 
         *              of the Visual Studio Designer, to supress the 
         *              "Object reference not set to an instance of an object" error
         *              that is displayed in the Design View
         *              - Dreas Grech.
         * */
        if (HttpContext.Current == null)
        {
            return new List<provider>();
        }
        /*
         * End Hack.
         * */

        if (HttpContext.Current.Cache[ProjectSettings.CacheKey] == null)
        {
            return null;
        }
        return (IEnumerable<provider>)HttpContext.Current.Cache[ProjectSettings.CacheKey];
    }
}

As you can see from the above code, I added a condition that checks if the HttpContext.Current is null and if it is, just returns a new List<provider>:

if (HttpContext.Current == null)
{
    return new List<provider>();
}