protected object UpdateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, object model) { bool cont = true; int index = 0; int notNullCount = 0; int prevErrors; List <int> trueIndexes = null; Type previousModelType = null; while (cont) { string displayPrefix = bindingContext.ModelName; if (displayPrefix == "model" || (bindingContext.ModelMetadata.PropertyName == null && !displayPrefix.Contains('.') && !displayPrefix.Contains('[') && !displayPrefix.Contains('$'))) { displayPrefix = "updatemodel"; } ValueProviderResult attemptedTransformer = bindingContext.ValueProvider.GetValue(displayPrefix + string.Format(".$${0}", index)); if (attemptedTransformer != null && attemptedTransformer.AttemptedValue != null) { Type displayModelType = BasicHtmlHelper.DecodeUpdateInfo(attemptedTransformer.AttemptedValue, previousModelType, bindingContext.ValueProvider); if (displayModelType != null && displayModelType.IsClass && displayModelType.GetInterface("IUpdateModel") != null) { prevErrors = bindingContext.ModelState.Keys.Count; previousModelType = displayModelType; IUpdateModel displayModel = BindDisplayModel(controllerContext, bindingContext, displayModelType, string.Format(".$${0}.$", index)) as IUpdateModel; if (trueIndexes == null) { trueIndexes = new List <int>(); } if (displayModel == null) { trueIndexes.Add(-1); } else { string[] fields = null; ValueProviderResult fieldsAttemptedTransformer = bindingContext.ValueProvider.GetValue(displayPrefix + string.Format(".$${0}.f$ields", index)); if (fieldsAttemptedTransformer != null && !string.IsNullOrWhiteSpace(fieldsAttemptedTransformer.AttemptedValue)) { fields = BasicHtmlHelper.DecodeFieldsInfo(fieldsAttemptedTransformer.AttemptedValue).Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); } else { fields = new string[0]; } int beforeElements = -1; ICollection beforeCollection = model as ICollection; if (beforeCollection != null) { beforeElements = beforeCollection.Count; } IUpdateModelState updateModelState = displayModel as IUpdateModelState; bool finished = false; if (updateModelState != null) { if (updateModelState.MoveState && index != notNullCount) { trueIndexes.Add(notNullCount); AlignModelState( bindingContext.ModelState, trueIndexes, LowerModelName(displayPrefix, ".$$")); finished = true; } updateModelState.GetCurrState(displayPrefix, notNullCount, bindingContext.ModelState); } IVisualState visualStateStorage = displayModel as IVisualState; if (visualStateStorage != null) { visualStateStorage.ModelName = bindingContext.ModelName; visualStateStorage.Store = controllerContext.HttpContext.Items; } IHandleUpdateIndex handleUpdateIndex = displayModel as IHandleUpdateIndex; if (handleUpdateIndex != null) { handleUpdateIndex.Index = index; handleUpdateIndex.ModelState = bindingContext.ModelState; } try { model = displayModel.UpdateModel(model, fields); } catch (Exception ex) { bindingContext.ModelState.AddModelError(bindingContext.ModelName, string.Format(ex.Message, bindingContext.ModelMetadata.GetDisplayName())); } if (finished) { break; } int afterElements = -1; ICollection afterCollection = model as ICollection; if (afterCollection != null) { afterElements = afterCollection.Count; } bool noCollections = afterElements == -1 && beforeElements == -1; if (model != null && (noCollections || beforeElements != afterElements)) { trueIndexes.Add(notNullCount); notNullCount++; } else { trueIndexes.Add(-1); } } } } else { if (index != notNullCount) { AlignModelState( bindingContext.ModelState, trueIndexes, LowerModelName(displayPrefix, ".$$")); } cont = false; break; } index++; } return(model); }