private async Task BindModelCoreAsync(IndexModelBindingContext bindingContext) { if (bindingContext.Model == null) { bindingContext.Model = CreateModel(bindingContext); } for (var i = 0; i < bindingContext.ModelMetadata.Properties.Count; i++) { var property = bindingContext.ModelMetadata.Properties[i]; if (!CanBindProperty(bindingContext, property)) { continue; } object propertyModel = null; if (property.PropertyGetter != null && property.IsComplexType && !property.ModelType.IsArray) { propertyModel = property.PropertyGetter(bindingContext.Model); } var fieldName = property.BinderModelName ?? property.PropertyName; var modelName = ModelNames.CreatePropertyModelName(bindingContext.ModelName, fieldName); ModelBindingResult result; using (bindingContext.EnterNestedScope( modelMetadata: property, fieldName: fieldName, modelName: modelName, model: propertyModel)) { await BindProperty(bindingContext); result = bindingContext.Result; } if (result.IsModelSet) { SetProperty(bindingContext, modelName, property, result); } else if (property.IsBindingRequired) { var message = property.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(fieldName); bindingContext.ModelState.TryAddModelError(modelName, message); } } bindingContext.Result = ModelBindingResult.Success(bindingContext.Model); }
private bool CanValueBindAnyModelProperties(IndexModelBindingContext bindingContext) { if (bindingContext.ModelMetadata.Properties.Count == 0) { return(false); } var hasBindableProperty = false; var isAnyPropertyEnabledForValueProviderBasedBinding = false; for (var i = 0; i < bindingContext.ModelMetadata.Properties.Count; i++) { var propertyMetadata = bindingContext.ModelMetadata.Properties[i]; if (!CanBindProperty(bindingContext, propertyMetadata)) { continue; } hasBindableProperty = true; var bindingSource = propertyMetadata.BindingSource; if (bindingSource == null || !bindingSource.IsGreedy) { isAnyPropertyEnabledForValueProviderBasedBinding = true; var fieldName = propertyMetadata.BinderModelName ?? propertyMetadata.PropertyName; var modelName = ModelNames.CreatePropertyModelName( bindingContext.ModelName, fieldName); using (bindingContext.EnterNestedScope( modelMetadata: propertyMetadata, fieldName: fieldName, modelName: modelName, model: null)) { if (bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { return(true); } } } } if (hasBindableProperty && !isAnyPropertyEnabledForValueProviderBasedBinding) { return(true); } return(false); }
internal async Task <CollectionResult> BindSimpleCollection( IndexModelBindingContext bindingContext, ValueProviderResult values) { var boundCollection = new List <TElement>(); var elementMetadata = bindingContext.ModelMetadata.ElementMetadata; foreach (var value in values) { bindingContext.ValueProvider = new CompositeValueProvider { // our temporary provider goes at the front of the list new ElementalValueProvider(bindingContext.ModelName, value, values.Culture), bindingContext.ValueProvider }; using (bindingContext.EnterNestedScope( elementMetadata, fieldName: bindingContext.FieldName, modelName: bindingContext.ModelName, model: null)) { await ElementBinder.BindModelAsync(bindingContext); if (bindingContext.Result.IsModelSet) { var boundValue = bindingContext.Result.Model; boundCollection.Add(IndexModelBinderHelper.CastOrDefault <TElement>(boundValue)); } } } return(new CollectionResult { Model = boundCollection }); }
internal async Task <CollectionResult> BindComplexCollectionFromIndexes( IndexModelBindingContext bindingContext, IEnumerable <string> indexNames) { bool indexNamesIsFinite; if (indexNames != null) { indexNamesIsFinite = true; } else { indexNamesIsFinite = false; indexNames = Enumerable.Range(0, int.MaxValue) .Select(i => i.ToString(CultureInfo.InvariantCulture)); } var elementMetadata = bindingContext.ModelMetadata.ElementMetadata; var boundCollection = new List <TElement>(); foreach (var indexName in indexNames) { var fullChildName = ModelNames.CreateIndexModelName(bindingContext.ModelName, indexName); var didBind = false; object boundValue = null; ModelBindingResult?result; using (bindingContext.EnterNestedScope( elementMetadata, fieldName: indexName, modelName: fullChildName, model: null)) { await ElementBinder.BindModelAsync(bindingContext); result = bindingContext.Result; } if (result != null && result.Value.IsModelSet) { didBind = true; boundValue = result.Value.Model; } // infinite size collection stops on first bind failure if (!didBind && !indexNamesIsFinite) { break; } boundCollection.Add(IndexModelBinderHelper.CastOrDefault <TElement>(boundValue)); } return(new CollectionResult { Model = boundCollection, ValidationStrategy = indexNamesIsFinite ? new ExplicitIndexCollectionValidationStrategy(indexNames) : null, }); }