internal static List <TElement> BindComplexCollectionFromIndexes(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext, IEnumerable <string> indexNames) { bool indexNamesIsFinite; if (indexNames != null) { indexNamesIsFinite = true; } else { indexNamesIsFinite = false; indexNames = CollectionModelBinderUtil.GetZeroBasedIndexes(); } List <TElement> boundCollection = new List <TElement>(); foreach (string indexName in indexNames) { string fullChildName = ModelBinderUtil.CreateIndexModelName(bindingContext.ModelName, indexName); ModelBindingContext childBindingContext = new ModelBindingContext(bindingContext) { ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(TElement)), ModelName = fullChildName }; object boundValue = null; IModelBinder childBinder = bindingContext.ModelBinderProviders.GetBinder(modelBindingExecutionContext, childBindingContext); if (childBinder != null) { if (childBinder.BindModel(modelBindingExecutionContext, childBindingContext)) { boundValue = childBindingContext.Model; // merge validation up bindingContext.ValidationNode.ChildNodes.Add(childBindingContext.ValidationNode); } } else { // should we even bother continuing? if (!indexNamesIsFinite) { break; } } boundCollection.Add(ModelBinderUtil.CastOrDefault <TElement>(boundValue)); } return(boundCollection); }
// Used when the ValueProvider contains the collection to be bound as a single element, e.g. the raw value // is [ "1", "2" ] and needs to be converted to an int[]. internal static List <TElement> BindSimpleCollection(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext, object rawValue, CultureInfo culture) { if (rawValue == null) { return(null); // nothing to do } List <TElement> boundCollection = new List <TElement>(); object[] rawValueArray = ModelBinderUtil.RawValueToObjectArray(rawValue); foreach (object rawValueElement in rawValueArray) { ModelBindingContext innerBindingContext = new ModelBindingContext(bindingContext) { ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(TElement)), ModelName = bindingContext.ModelName, ValueProvider = new ValueProviderCollection() // aggregate value provider { new ElementalValueProvider(bindingContext.ModelName, rawValueElement, culture), // our temporary provider goes at the front of the list bindingContext.ValueProvider } }; object boundValue = null; IModelBinder childBinder = bindingContext.ModelBinderProviders.GetBinder(modelBindingExecutionContext, innerBindingContext); if (childBinder != null) { if (childBinder.BindModel(modelBindingExecutionContext, innerBindingContext)) { boundValue = innerBindingContext.Model; bindingContext.ValidationNode.ChildNodes.Add(innerBindingContext.ValidationNode); } } boundCollection.Add(ModelBinderUtil.CastOrDefault <TElement>(boundValue)); } return(boundCollection); }