簡體   English   中英

System.Web.Mvc.FilterProviderCollection.GetFilters上的NullReferenceException

[英]NullReferenceException at System.Web.Mvc.FilterProviderCollection.GetFilters

我在Windows 2008 R2(IIS 7.5)上運行了MVC 5應用(.NET 4.5.1)

在運行負載測試時,會定期拋出以下異常。 不幸的是,我無法在本地復制,而陷入困境,所以希望社區中可以有更多的想法。 更新:現在已經能夠在負載下再現

查看FilterProviderCollection.GetFilters的源可能表明它可能是依賴解析器-但是由於沒有更多信息,我不願意簡單地替換該庫。 目前其使用SimpleInjector。

如果是這種情況,我的猜測是由應用程序池回收引起的,但無法確認(在應用程序池中啟用所有導致回收的原因的日志記錄,這對我沒有任何幫助)

經過大量搜索,我確實找到了一些可能是Glimpse的參考。 我已經確認情況並非如此。 我還剝離並重建了該項目,以使人們確信它不僅僅是簡單的nuget-package升級怪異。

任何有關可能導致它的建議,或者我如何添加額外的日志記錄以捕獲更多信息,將不勝感激。 謝謝。

Exception information: 
    Exception type: NullReferenceException 
    Exception message: Object reference not set to an instance of an object.
   at System.Web.Mvc.FilterProviderCollection.GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
   at System.Web.Mvc.ControllerActionInvoker.GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state)
   at System.Web.Mvc.Controller.<BeginExecuteCore>b__1c(AsyncCallback asyncCallback, Object asyncState, ExecuteCoreState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TState](AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext)
   at System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TState](AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext)
   at System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state)
   at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(AsyncCallback asyncCallback, Object asyncState, ProcessRequestState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout)
   at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TState](AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext)
   at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

更新1

我已經能夠找到一種在測試環境中復制的方法:

  1. 不斷增加應用程序的負載(最多20個虛擬用戶)
  2. 手動回收應用程序池(直到失敗觸發為止)

在沒有負載的情況下回收應用程序池似乎不會觸發故障。

更令人擔憂的是,將“禁用重疊回收”設置為True不會阻止它們的發生。 我以為這將停止任何回收問題,因為它在啟動新的回收程序之前會完全破壞工作進程。

更新2

(對我而言)Global.asax和關聯的配置看起來與默認模板相距不遠。 明白你的想法嗎?

    public class MyHttpApplication : HttpApplication {

            public MyHttpApplication() {
                    SimpleInjectorConfig.InitializeContainer(); //seems to need to be in ctor to support HttpModule dependencies
            }

            protected void Application_Start() {
                    MvcHandler.DisableMvcResponseHeader = true;

                    AreaRegistration.RegisterAllAreas();

                    ViewEngineConfig.RegisterViewEngines(ViewEngines.Engines);
                    WebApiConfig.Register(GlobalConfiguration.Configuration);
                    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                    RouteConfig.RegisterRoutes(RouteTable.Routes);
                    BinderConfig.RegisterGlobalBinders(ModelBinders.Binders);
            }

各種XxxConfig類幾乎不在模板中。

    public static class FilterConfig {
            public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
                    filters.Add(new AuthorizeAttribute());
            }
    }

    public static class SimpleInjectorConfig {
            /// <summary>Initialize the container and register it as MVC Dependency Resolver.</summary>
            public static void InitializeContainer() {
                    var container = new Container();
                    container.Options.AllowResolvingFuncFactories();

                    RegisterServices(container);

                    container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
                    container.RegisterMvcIntegratedFilterProvider();
                    container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

                    //container.Verify(); //see http://bit.ly/YE8OJj for more info

                    DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
                    GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
            }

更新3

在進行重疊回收的情況下運行時,我能夠獲得以下變體堆棧跟蹤。

[IndexOutOfRangeException: Index was outside the bounds of the array.]
   System.Collections.Generic.Enumerator.MoveNext() +112
   System.Linq.<ConcatIterator>d__71`1.MoveNext() +643
   System.Linq.Buffer`1..ctor(IEnumerable`1 source) +520
   System.Linq.Enumerable.ToArray(IEnumerable`1 source) +103
   System.Web.Mvc.FilterProviderCollection.GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +89
   System.Web.Mvc.ControllerActionInvoker.GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +38
   System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +333
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1c(AsyncCallback asyncCallback, Object asyncState, ExecuteCoreState innerState) +45
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +111
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +150
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +203
   System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +879
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +150
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +154
   System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +527
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(AsyncCallback asyncCallback, Object asyncState, ProcessRequestState innerState) +108
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +111
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +150
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +203
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +665
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +12638163
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288

[IndexOutOfRangeException: Index was outside the bounds of the array.]
   System.Collections.Generic.Enumerator.MoveNext() +112
   System.Linq.<OfTypeIterator>d__aa`1.MoveNext() +344
   System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +536
   System.Linq.Enumerable.ToList(IEnumerable`1 source) +80
   SimpleInjector.SimpleInjectorMvcExtensions.RegisterMvcIntegratedFilterProvider(Container container) +271
   WebProject.SimpleInjectorConfig.InitializeContainer() in c:\...\App_Start\SimpleInjectorConfig.cs:35
   WebProject.MyHttpApplication..ctor() in c:\...\Global.asax.cs:14
   ASP.global_asax..ctor() in c:\...\App_global.asax.3szzcx02.0.cs:0

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
   System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +159
   System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +256
   System.Activator.CreateInstance(Type type, Boolean nonPublic) +127
   System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark) +14259433
   System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) +200
   System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture) +28
   System.Web.HttpRuntime.CreateNonPublicInstance(Type type, Object[] args) +83
   System.Web.HttpApplicationFactory.GetNormalApplicationInstance(HttpContext context) +246
   System.Web.HttpApplicationFactory.GetApplicationInstance(HttpContext context) +178
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +333

以下行給您帶來麻煩:

public MyHttpApplication() {
    SimpleInjectorConfig.InitializeContainer(); //seems to need to be in c...    
}

可以多次調用MyHttpApplication ,這將導致創建多個容器,每個容器都嘗試使用RegisterMvcIntegratedFilterProvider將自身注冊為過濾器提供程序。 您應該確保僅為該應用程序域創建一個容器實例,因此您只需調用一次RegisterMvcIntegratedFilterProvider

首先,感謝史蒂文在分析問題上的幫助。

原來問題是由於SimpleInjectorConfig.InitializeContainer的位置無害。

盡管ASP.NET運行時確保Application_Start僅被調用一次,但它可以創建多個HttpApplication。 在ctor中進行調用意味着在負載下回收時,本應運行一次的初始化最終被多次調用。

public MyHttpApplication() {
  SimpleInjectorConfig.InitializeContainer(); //WRONG
}

將其移至Application_Start可解決當前的問題。

protected void Application_Start() {
  SimpleInjectorConfig.InitializeContainer();
}

鑒於該調用僅在Ctor中提供了對IHttpModule的支持,因此我還采取了進一步的步驟,使依賴項能夠注入到IHttpModule的依賴中。 HttpModuleMagic對此非常有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM