16

We have this error occurring very frequently in an MVC 5.1.3 application, when it does happen, the user has to refresh the page and it does away, so its an intermittent issue.

We have found it tricky to diagnose as it appears to happen within the framework itself. Any ideas on where to look?

This is the full stack:

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
   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.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.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

There has been a similar question asked before: Collection was modified; enumeration operation may not execute, but this was resolved by upgrading to MVC 5, we already on 5.

Community
  • 1
  • 1
Dan
  • 29,100
  • 43
  • 148
  • 207
  • On which code you get this ? – Mairaj Ahmad Apr 15 '15 at 04:26
  • 4
    Obviously something is adding or removing a filter from your global filters collection at runtime. This is something that should only happen at startup, so the first thing you should do is search for anywhere the global filters are modified, and anywhere it's done that's not in startup is suspect. – Erik Funkenbusch Apr 16 '15 at 01:06
  • Have you used any other tools to get a better look at what is happening? like [Elmah](https://github.com/alexbeletsky/elmah-mvc) or [glimpse](http://getglimpse.com/) –  Apr 17 '15 at 12:08
  • Can you put your code as well. If you are using custom filters, check in which orders they are executing. It seems in 5.1.3 they are getting asynchronously executed and struggling to get the same resource from controllercontext. – Lalit Kale Apr 18 '15 at 10:53

1 Answers1

4

As @Erik said in a comment, obviously the collection of filters are being modified during the execution of the requests, where it should only be populated during application start up.

One possibility is that you've registered a custom IFilterProvider which is breaking the code. Here's the source code from where the error occurs (from FilterProviderCollection)

        for (int i = 0; i < providers.Length; i++)
        {
            IFilterProvider provider = providers[i];
            foreach (Filter filter in provider.GetFilters(controllerContext, actionDescriptor))
            {
                filters.Add(filter);
            }
        }

The provider.GetFilter(...) is returning a List which is later modified during enumeration in the FilterProviderCollection's foreach block.

Here's what comes to my mind for you to test:

  • First of all, make sure you're not registering a custom IFilterProvider (either you, or a library you might be using). If so, that is the primary suspect.

  • Look for all usages of GlobalFilterCollection and GlobalFilters class in your code. Any modification to this collection should only be reached from Application_Start in Global.asax or the Startup class (if you're using OWIN)

  • Look for clues where you're creating filters or accessing them.

  • Try upgrading to MVC 5.2. If it's an issue with the framework (which seems unlikely) this may fix it. (I'm using 5.2.2.0 and don't see any similar issues in either development or production)

  • Debug your application, and set a break point in the beginning of Application_BeginRequest and in the controller action. Try to inspect the global filters collection and see if there's any change.

  • Maybe registering a custom IFilterProvider and inspecting the behavior by debugging or logging can be helpful.

Iravanchi
  • 5,139
  • 9
  • 40
  • 56