Question

I am receiving an error from the SharpArchitecture model binder. "Collection was modified; enumeration operation may not execute." (Stack trace at the bottom).

My MVC pages to create and edit my SettingsModel throw the error. This started happening when we upgraded to the release version of S#arp Architecture 1.0. My class has a few Lists as properties. One of the Lists contains classes with other another List as a property. I'm not sure which List is throwing the error. Can anyone provide direction as to how to troubleshoot this or things to look for in my models that might cause it?

This is my SettingsModel class:

public class SettingsModel : Entity
 {
  public SettingsModel() 
  {
   AttributeSettingsList = new List<AttributeSettingsModel>();
  }

  public virtual void AddAttributeSettings(AttributeSettingsModel attSettings)
  {
   AttributeSettingsList.Add(attSettings);
   attSettings.Settings = this;
  }


  [NotNullNotEmpty(Message = "Description must be provided")]
  public virtual string Description { get; set; }

  [DomainSignature]
  [Range(0, 100, Message = "ModelAPercentage must be between 0 and 100")]
  public virtual int ModelAPercentage { get; set; }

  [DomainSignature]
  [Range(0, 100, Message = "ModelBPercentage must be between 0 and 100")]
  public virtual int ModelBPercentage { get; set; }

  public virtual IList<AttributeSettingsModel> AttributeSettingsList { get; set; }

  public virtual IList<EntityMappingModel> EntityMappingList { get; set; }

  public SettingsModel(string Description, int ModelAPercentage, int ModelBPercentage)
   : this() 
  {
   this.Description = Description;
   this.ModelAPercentage = ModelAPercentage;
   this.ModelBPercentage = ModelBPercentage;
  }

 }

This is the SharpArchitecture method throwing the error:

    private void SetEntityCollectionProperty(ModelBindingContext bindingContext,
        PropertyDescriptor propertyDescriptor, object value) {

        if (value as IEnumerable != null &&
            IsSimpleGenericBindableEntityCollection(propertyDescriptor.PropertyType)) {

            object entityCollection = propertyDescriptor.GetValue(bindingContext.Model);
            Type entityCollectionType = entityCollection.GetType();

            foreach (object entity in (value as IEnumerable)) {
                entityCollectionType.InvokeMember("Add",
                    BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, entityCollection,
                    new object[] { entity });
            }
        }
    }

Here is the stack trace:

[InvalidOperationException: Collection was modified; enumeration operation may not execute.] System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) +51 System.Collections.Generic.Enumerator.MoveNextRare() +7661017 System.Collections.Generic.Enumerator.MoveNext() +61 SharpArch.Web.ModelBinder.SharpModelBinder.SetEntityCollectionProperty(ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, Object value) +358 SharpArch.Web.ModelBinder.SharpModelBinder.SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, Object value) +61 System.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) +265 SharpArch.Web.ModelBinder.SharpModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) +225 System.Web.Mvc.DefaultModelBinder.BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) +125 System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +293 System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +772 System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +345 SharpArch.Web.ModelBinder.SharpModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +39 System.Web.Mvc.DefaultModelBinder.UpdateCollection(ControllerContext controllerContext, ModelBindingContext bindingContext, Type elementType) +408 System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +756 System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +345 SharpArch.Web.ModelBinder.SharpModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +39 System.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) +231 SharpArch.Web.ModelBinder.SharpModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) +225 System.Web.Mvc.DefaultModelBinder.BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) +125 System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +293 System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +772 System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +345 SharpArch.Web.ModelBinder.SharpModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +39 System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +219 System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +109 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +399 System.Web.Mvc.Controller.ExecuteCore() +126 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +27 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +7 System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) +151 System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) +57 System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) +7 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

Was it helpful?

Solution

There appears to be a bug in the sharp architecture SetEntityCollectionProperty method. Its in the last four lines:

        foreach (object entity in (value as IEnumerable)) {
            entityCollectionType.InvokeMember("Add",
                BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, entityCollection,
                new object[] { entity });
        }

Its intent seems to be to populate the model collection class (entityCollection) from the values in the IEnumerable passed in as value. However, these two objects are the same reference. It's already populated. When the "Add" method is invoked, the entityCollection is modified which is the same object that is being iterated. Then the exception is thrown.

Comment or delete that code block and your code should run.

OTHER TIPS

Do comment this block of code affect other functions of S#arp?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top