NullReferenceException in WebConfigScopeDictionary

Sometimes (about once a month) an ASP.NET MVC 3 web application crashes with this exception.

System.NullReferenceException: Object reference not set to an instance of an object.

Server stack trace: 
   at System.Collections.Specialized.NameObjectCollectionBase.BaseGetAllKeys()
   at System.Collections.Specialized.NameValueCollection.get_AllKeys()
   at System.Web.WebPages.Scope.WebConfigScopeDictionary.<>c__DisplayClass4.<.ctor>b__0()
   at System.Lazy`1.CreateValue()

Exception rethrown at [0]: 
   at System.Lazy`1.get_Value()
   at System.Web.WebPages.Scope.WebConfigScopeDictionary.TryGetValue(Object key, Object& value)
   at System.Web.Mvc.ViewContext.ScopeGet[TValue](IDictionary`2 scope, String name, TValue defaultValue)
   at System.Web.Mvc.ViewContext.ScopeCache..ctor(IDictionary`2 scope)
   at System.Web.Mvc.ViewContext.ScopeCache.Get(IDictionary`2 scope, HttpContextBase httpContext)
   at System.Web.Mvc.ViewContext.GetClientValidationEnabled(IDictionary`2 scope, HttpContextBase httpContext)
   at System.Web.Mvc.Html.FormExtensions.FormHelper(HtmlHelper htmlHelper, String formAction, FormMethod method, IDictionary`2 htmlAttributes)
   at ASP._Page_Views_mywebpage_Create_cshtml.Execute() in c:\App\Views\Mywebpage\Create.cshtml:line 11
   at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
   at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
   at System.Web.WebPages.StartPage.ExecutePageHierarchy()
   at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
   at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at System.Web.Mvc.Controller.ExecuteCore()
   at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
   at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.<BeginProcessRequest>b__5()
   at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

      

This exception is thrown on the line with

@using (Html.BeginForm())

      

Once this exception is thrown, the application is unusable once. Every view will start throwing this error. I have looked through the source code but I don't seem to find anything. There are people who experience the same behavior, but with different error and or using different code .

As you dig deeper into the WebConfigScopeDictionary source, you can see the AppSettings being read:

public WebConfigScopeDictionary() : this(WebConfigurationManager.AppSettings)
{
}
public WebConfigScopeDictionary(NameValueCollection appSettings)
{
    this._items = new Lazy<Dictionary<object, object>>(() => appSettings.AllKeys.ToDictionary((string key) => key, (string key) => appSettings[key], ScopeStorageComparer.Instance));
}

      

The appsettings settings are taken from the ConfigurationManager:

public static NameValueCollection AppSettings
{
    get
    {
        object section = ConfigurationManager.GetSection("appSettings");
        if (section == null || !(section is NameValueCollection))
        {
            throw new ConfigurationErrorsException(SR.GetString("Config_appsettings_declaration_invalid"));
        }
        return (NameValueCollection)section;
    }
}

      

If there was a problem with the web.config, this code should throw an exception. But this is not the case. Ultimately count is called on the collection that is returned by the AppSettings. Since it is probably null, it is throwing.

protected string[] BaseGetAllKeys()
{
    int count = this._entriesArray.Count;
    string[] array = new string[count];
    for (int i = 0; i < count; i++)
    {
        array[i] = this.BaseGetKey(i);
    }
    return array;
}

      

If anyone has any ideas, feel free to share them.

+3


source to share


1 answer


After prompting for the ops command, it seems that the application pool has been recycled after it timed out. This happened while working in the office when the application was under heavy load. We have now changed it to reuse at specific times, which is still a workaround, but should prevent the problem from occurring too often.



0


source







All Articles