public async Task <ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext); if (bindingContext.ModelMetadata.IsComplexType) { // this type cannot be converted return(null); } var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName); if (valueProviderResult == null) { return(null); // no entry } object newModel; bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); try { newModel = valueProviderResult.ConvertTo(bindingContext.ModelType); ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref newModel); var validationNode = new ModelValidationNode( bindingContext.ModelName, bindingContext.ModelMetadata, newModel); var isModelSet = true; // When converting newModel a null value may indicate a failed conversion for an otherwise required // model (can't set a ValueType to null). This detects if a null model value is acceptable given the // current bindingContext. If not, an error is logged. if (newModel == null && !AllowsNullValue(bindingContext.ModelType)) { bindingContext.ModelState.TryAddModelError( bindingContext.ModelName, Resources.FormatCommon_ValueNotValidForProperty(newModel)); isModelSet = false; } return(new ModelBindingResult(newModel, bindingContext.ModelName, isModelSet, validationNode)); } catch (Exception ex) { bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, ex); } // Were able to find a converter for the type but conversion failed. // Tell the model binding system to skip other model binders i.e. return non-null. return(new ModelBindingResult(model: null, key: bindingContext.ModelName, isModelSet: false)); }
internal async Task <IEnumerable <TElement> > BindComplexCollectionFromIndexes(ModelBindingContext bindingContext, IEnumerable <string> indexNames) { bool indexNamesIsFinite; if (indexNames != null) { indexNamesIsFinite = true; } else { indexNamesIsFinite = false; indexNames = Enumerable.Range(0, Int32.MaxValue) .Select(i => i.ToString(CultureInfo.InvariantCulture)); } var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider; var elementMetadata = metadataProvider.GetMetadataForType(typeof(TElement)); var boundCollection = new List <TElement>(); foreach (var indexName in indexNames) { var fullChildName = ModelBindingHelper.CreateIndexModelName(bindingContext.ModelName, indexName); var childBindingContext = ModelBindingContext.GetChildModelBindingContext( bindingContext, fullChildName, elementMetadata); var didBind = false; object boundValue = null; var modelType = bindingContext.ModelType; var result = await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(childBindingContext); if (result != null) { didBind = true; boundValue = result.Model; } // infinite size collection stops on first bind failure if (!didBind && !indexNamesIsFinite) { break; } boundCollection.Add(ModelBindingHelper.CastOrDefault <TElement>(boundValue)); } return(boundCollection); }
internal void ProcessDto(ModelBindingContext bindingContext, ComplexModelDto dto) { var validationInfo = GetPropertyValidationInfo(bindingContext); // Eliminate provided properties from requiredProperties; leaving just *missing* required properties. validationInfo.RequiredProperties.ExceptWith(dto.Results.Select(r => r.Key.PropertyName)); foreach (var missingRequiredProperty in validationInfo.RequiredProperties) { var addedError = false; var modelStateKey = ModelBindingHelper.CreatePropertyModelName( bindingContext.ValidationNode.ModelStateKey, missingRequiredProperty); // Update Model as SetProperty() would: Place null value where validator will check for non-null. This // ensures a failure result from a required validator (if any) even for a non-nullable property. // (Otherwise, propertyMetadata.Model is likely already null.) var propertyMetadata = bindingContext.PropertyMetadata[missingRequiredProperty]; propertyMetadata.Model = null; // Execute validator (if any) to get custom error message. IModelValidator validator; if (validationInfo.RequiredValidators.TryGetValue(missingRequiredProperty, out validator)) { addedError = RunValidator(validator, bindingContext, propertyMetadata, modelStateKey); } // Fall back to default message if BindingBehaviorAttribute required this property or validator // (oddly) succeeded. if (!addedError) { bindingContext.ModelState.TryAddModelError( modelStateKey, Resources.FormatMissingRequiredMember(missingRequiredProperty)); } } // for each property that was bound, call the setter, recording exceptions as necessary foreach (var entry in dto.Results) { var propertyMetadata = entry.Key; var dtoResult = entry.Value; if (dtoResult != null) { IModelValidator requiredValidator; validationInfo.RequiredValidators.TryGetValue(propertyMetadata.PropertyName, out requiredValidator); SetProperty(bindingContext, propertyMetadata, dtoResult, requiredValidator); bindingContext.ValidationNode.ChildNodes.Add(dtoResult.ValidationNode); } } }
public async Task <ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext, typeof(KeyValuePair <TKey, TValue>), allowNullModel: true); var keyResult = await TryBindStrongModel <TKey>(bindingContext, "Key"); var valueResult = await TryBindStrongModel <TValue>(bindingContext, "Value"); if (keyResult.IsModelSet && valueResult.IsModelSet) { var model = new KeyValuePair <TKey, TValue>( ModelBindingHelper.CastOrDefault <TKey>(keyResult.Model), ModelBindingHelper.CastOrDefault <TValue>(valueResult.Model)); return(ModelBindingResult.Success(bindingContext.ModelName, model)); } else if (!keyResult.IsModelSet && valueResult.IsModelSet) { bindingContext.ModelState.TryAddModelError( keyResult.Key, bindingContext.ModelMetadata.ModelBindingMessageProvider.MissingKeyOrValueAccessor()); // Were able to get some data for this model. // Always tell the model binding system to skip other model binders. return(ModelBindingResult.Failed(bindingContext.ModelName)); } else if (keyResult.IsModelSet && !valueResult.IsModelSet) { bindingContext.ModelState.TryAddModelError( valueResult.Key, bindingContext.ModelMetadata.ModelBindingMessageProvider.MissingKeyOrValueAccessor()); // Were able to get some data for this model. // Always tell the model binding system to skip other model binders. return(ModelBindingResult.Failed(bindingContext.ModelName)); } else { // If we failed to find data for a top-level model, then generate a // default 'empty' model and return it. if (bindingContext.IsTopLevelObject) { var model = new KeyValuePair <TKey, TValue>(); return(ModelBindingResult.Success(bindingContext.ModelName, model)); } return(ModelBindingResult.NoResult); } }
// 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 for testing. internal async Task <CollectionResult> BindSimpleCollection( ModelBindingContext bindingContext, object rawValue, CultureInfo culture) { var boundCollection = new List <TElement>(); var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider; var elementMetadata = metadataProvider.GetMetadataForType(typeof(TElement)); var validationNode = new ModelValidationNode( bindingContext.ModelName, bindingContext.ModelMetadata, boundCollection); var rawValueArray = RawValueToObjectArray(rawValue); foreach (var rawValueElement in rawValueArray) { var innerBindingContext = ModelBindingContext.GetChildModelBindingContext( bindingContext, bindingContext.ModelName, elementMetadata); innerBindingContext.ValueProvider = new CompositeValueProvider { // our temporary provider goes at the front of the list new ElementalValueProvider(bindingContext.ModelName, rawValueElement, culture), bindingContext.ValueProvider }; object boundValue = null; var result = await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(innerBindingContext); if (result != null && result.IsModelSet) { boundValue = result.Model; if (result.ValidationNode != null) { validationNode.ChildNodes.Add(result.ValidationNode); } } boundCollection.Add(ModelBindingHelper.CastOrDefault <TElement>(boundValue)); } return(new CollectionResult { ValidationNode = validationNode, Model = boundCollection }); }
/// <summary> /// Attempts to convert the values in <paramref name="result"/> to the specified type. /// </summary> /// <param name="result">The <see cref="ValueProviderResult"/>.</param> /// <param name="type">The <see cref="Type"/> for conversion.</param> /// <returns> /// The converted value, or the default value of <paramref name="type"/> if the value could not be converted. /// </returns> public static object ConvertTo(this ValueProviderResult result, [NotNull] Type type) { object valueToConvert = null; if (result.Values.Count == 1) { valueToConvert = result.Values[0]; } else if (result.Values.Count > 1) { valueToConvert = result.Values.ToArray(); } return(ModelBindingHelper.ConvertTo(valueToConvert, type, result.Culture)); }
/// <summary> /// Attempts to convert the values in <paramref name="result"/> to the specified type. /// </summary> /// <typeparam name="T">The <see cref="Type"/> for conversion.</typeparam> /// <param name="result">The <see cref="ValueProviderResult"/>.</param> /// <returns> /// The converted value, or the default value of <typeparamref name="T"/> if the value could not be converted. /// </returns> public static T ConvertTo <T>(this ValueProviderResult result) { object valueToConvert = null; if (result.Values.Count == 1) { valueToConvert = result.Values[0]; } else if (result.Values.Count > 1) { valueToConvert = result.Values.ToArray(); } return(ModelBindingHelper.ConvertTo <T>(valueToConvert, result.Culture)); }
/// <inheritdoc /> protected override Task <ModelBindingResult> BindModelCoreAsync([NotNull] ModelBindingContext bindingContext) { var request = bindingContext.OperationBindingContext.HttpContext.Request; var modelMetadata = bindingContext.ModelMetadata; // Property name can be null if the model metadata represents a type (rather than a property or parameter). var headerName = bindingContext.BinderModelName ?? modelMetadata.PropertyName ?? bindingContext.ModelName; object model = null; if (bindingContext.ModelType == typeof(string)) { var value = request.Headers.Get(headerName); if (value != null) { model = value; } } else if (typeof(IEnumerable <string>).IsAssignableFrom(bindingContext.ModelType)) { var values = request.Headers.GetCommaSeparatedValues(headerName); if (values != null) { model = ModelBindingHelper.ConvertValuesToCollectionType( bindingContext.ModelType, values); } } ModelValidationNode validationNode = null; if (model != null) { validationNode = new ModelValidationNode( bindingContext.ModelName, bindingContext.ModelMetadata, model); var attemptedValue = (model as string) ?? request.Headers.Get(headerName); var valueProviderResult = new ValueProviderResult(model, attemptedValue, CultureInfo.InvariantCulture); bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); } return(Task.FromResult( new ModelBindingResult( model, bindingContext.ModelName, isModelSet: model != null, validationNode: validationNode))); }
public async Task <ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) { var valueProviderResult = await GetCompatibleValueProviderResult(bindingContext); if (valueProviderResult == null) { // conversion would have failed return(null); } bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); var model = valueProviderResult.RawValue; ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref model); return(new ModelBindingResult(model, bindingContext.ModelName, isModelSet: true)); }
public async Task <bool> BindModelAsync(ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext, typeof(KeyValuePair <TKey, TValue>), allowNullModel: true); var keyResult = await TryBindStrongModel <TKey>(bindingContext, "key"); var valueResult = await TryBindStrongModel <TValue>(bindingContext, "value"); if (keyResult.Success && valueResult.Success) { bindingContext.Model = new KeyValuePair <TKey, TValue>(keyResult.Model, valueResult.Model); } return(keyResult.Success || valueResult.Success); }
public async Task <ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext, typeof(KeyValuePair <TKey, TValue>), allowNullModel: true); var keyResult = await TryBindStrongModel <TKey>(bindingContext, "Key"); var valueResult = await TryBindStrongModel <TValue>(bindingContext, "Value"); if (keyResult.IsModelSet && valueResult.IsModelSet) { var model = new KeyValuePair <TKey, TValue>( ModelBindingHelper.CastOrDefault <TKey>(keyResult.Model), ModelBindingHelper.CastOrDefault <TValue>(valueResult.Model)); // Success return(new ModelBindingResult(model, bindingContext.ModelName, isModelSet: true)); } else if (!keyResult.IsModelSet && valueResult.IsModelSet) { bindingContext.ModelState.TryAddModelError( keyResult.Key, Resources.KeyValuePair_BothKeyAndValueMustBePresent); // Were able to get some data for this model. // Always tell the model binding system to skip other model binders i.e. return non-null. return(new ModelBindingResult(model: null, key: bindingContext.ModelName, isModelSet: false)); } else if (keyResult.IsModelSet && !valueResult.IsModelSet) { bindingContext.ModelState.TryAddModelError( valueResult.Key, Resources.KeyValuePair_BothKeyAndValueMustBePresent); // Were able to get some data for this model. // Always tell the model binding system to skip other model binders i.e. return non-null. return(new ModelBindingResult(model: null, key: bindingContext.ModelName, isModelSet: false)); } else { // Caller (GenericModelBinder) was able to resolve a binder type and will create a ModelBindingResult // that exits current ModelBinding loop. return(null); } }
internal static async Task <ValueProviderResult> GetCompatibleValueProviderResult(ModelBindingContext context) { ModelBindingHelper.ValidateBindingContext(context); var valueProviderResult = await context.ValueProvider.GetValueAsync(context.ModelName); if (valueProviderResult == null) { return(null); // the value doesn't exist } if (!context.ModelType.IsCompatibleWith(valueProviderResult.RawValue)) { return(null); // value is of incompatible type } return(valueProviderResult); }
public async Task <ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext); if (bindingContext.ModelMetadata.IsComplexType) { // this type cannot be converted return(null); } var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName); if (valueProviderResult == null) { return(null); // no entry } object newModel; bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); try { newModel = valueProviderResult.ConvertTo(bindingContext.ModelType); ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref newModel); var validationNode = new ModelValidationNode( bindingContext.ModelName, bindingContext.ModelMetadata, newModel); return(new ModelBindingResult( newModel, bindingContext.ModelName, isModelSet: true, validationNode: validationNode)); } catch (Exception ex) { bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, ex); } // Were able to find a converter for the type but conversion failed. // Tell the model binding system to skip other model binders i.e. return non-null. return(new ModelBindingResult(model: null, key: bindingContext.ModelName, isModelSet: false)); }
/// <summary> /// Attempts to convert the values in <paramref name="result"/> to the specified type. /// </summary> /// <param name="result">The <see cref="ValueProviderResult"/>.</param> /// <param name="type">The <see cref="Type"/> for conversion.</param> /// <returns> /// The converted value, or the default value of <paramref name="type"/> if the value could not be converted. /// </returns> public static object ConvertTo(this ValueProviderResult result, Type type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } object valueToConvert = null; if (result.Values.Count == 1) { valueToConvert = result.Values[0]; } else if (result.Values.Count > 1) { valueToConvert = result.Values.ToArray(); } return(ModelBindingHelper.ConvertTo(valueToConvert, type, result.Culture)); }
public virtual async Task <bool> BindModelAsync(ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext); if (!await bindingContext.ValueProvider.ContainsPrefixAsync(bindingContext.ModelName)) { return(false); } var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName); var bindCollectionTask = valueProviderResult != null? BindSimpleCollection(bindingContext, valueProviderResult.RawValue, valueProviderResult.Culture) : BindComplexCollection(bindingContext); var boundCollection = await bindCollectionTask; return(CreateOrReplaceCollection(bindingContext, boundCollection)); }
// Validates a single node (not including children) // Returns true if validation passes successfully private static bool ShallowValidate( ModelMetadata metadata, ValidationContext validationContext, [NotNull] IEnumerable <IModelValidator> validators) { var isValid = true; string modelKey = null; // When the are no validators we bail quickly. This saves a GetEnumerator allocation. // In a large array (tens of thousands or more) scenario it's very significant. var validatorsAsCollection = validators as ICollection; if (validatorsAsCollection != null && validatorsAsCollection.Count == 0) { return(isValid); } var modelValidationContext = new ModelValidationContext(validationContext.ModelValidationContext, metadata); foreach (var validator in validators) { foreach (var error in validator.Validate(modelValidationContext)) { if (modelKey == null) { modelKey = validationContext.RootPrefix; // This constructs the object heirarchy // Example: prefix.Parent.Child foreach (var keyBuilder in validationContext.KeyBuilders.Reverse()) { modelKey = keyBuilder.AppendTo(modelKey); } } var errorKey = ModelBindingHelper.CreatePropertyModelName(modelKey, error.MemberName); validationContext.ModelValidationContext.ModelState.AddModelError(errorKey, error.Message); isValid = false; } } return(isValid); }
public async Task <bool> BindModelAsync(ModelBindingContext bindingContext) { var valueProviderResult = await GetCompatibleValueProviderResult(bindingContext); if (valueProviderResult == null) { // conversion would have failed return(false); } bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); var model = valueProviderResult.RawValue; ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref model); bindingContext.Model = model; // TODO: Determine if we need IBodyValidator here. return(true); }
/// <inheritdoc /> public async Task <ModelBindingResult> BindModelAsync([NotNull] ModelBindingContext bindingContext) { object value; if (bindingContext.ModelType == typeof(IFormFile)) { var postedFiles = await GetFormFilesAsync(bindingContext); value = postedFiles.FirstOrDefault(); } else if (typeof(IEnumerable <IFormFile>).IsAssignableFrom(bindingContext.ModelType)) { var postedFiles = await GetFormFilesAsync(bindingContext); value = ModelBindingHelper.ConvertValuesToCollectionType(bindingContext.ModelType, postedFiles); } else { // This binder does not support the requested type. return(null); } ModelValidationNode validationNode = null; if (value != null) { validationNode = new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, value) { SuppressValidation = true, }; var valueProviderResult = new ValueProviderResult(rawValue: value); bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); } return(new ModelBindingResult( value, bindingContext.ModelName, isModelSet: value != null, validationNode: validationNode)); }
internal async Task <BindResult <TModel> > TryBindStrongModel <TModel>(ModelBindingContext parentBindingContext, string propertyName) { var propertyBindingContext = new ModelBindingContext(parentBindingContext) { ModelMetadata = parentBindingContext.MetadataProvider.GetMetadataForType(modelAccessor: null, modelType: typeof(TModel)), ModelName = ModelBindingHelper.CreatePropertyModelName(parentBindingContext.ModelName, propertyName) }; if (await propertyBindingContext.ModelBinder.BindModelAsync(propertyBindingContext)) { var untypedModel = propertyBindingContext.Model; var model = ModelBindingHelper.CastOrDefault <TModel>(untypedModel); parentBindingContext.ValidationNode.ChildNodes.Add(propertyBindingContext.ValidationNode); return(new BindResult <TModel>(success: true, model: model)); } return(new BindResult <TModel>(success: false, model: default(TModel))); }
public virtual async Task <bool> BindModelAsync(ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext); if (!CanBindType(bindingContext.ModelType) || !await bindingContext.ValueProvider.ContainsPrefixAsync(bindingContext.ModelName)) { return(false); } EnsureModel(bindingContext); var propertyMetadatas = GetMetadataForProperties(bindingContext); var dto = CreateAndPopulateDto(bindingContext, propertyMetadatas); // post-processing, e.g. property setters and hooking up validation ProcessDto(bindingContext, dto); // complex models require full validation bindingContext.ValidationNode.ValidateAllProperties = true; return(true); }
/// <inheritdoc /> public async Task <ModelBindingResult> BindModelAsync([NotNull] ModelBindingContext bindingContext) { if (bindingContext.ModelType == typeof(IFormFile)) { var postedFiles = await GetFormFilesAsync(bindingContext); var value = postedFiles.FirstOrDefault(); return(new ModelBindingResult(value, bindingContext.ModelName, isModelSet: value != null)); } else if (typeof(IEnumerable <IFormFile>).GetTypeInfo().IsAssignableFrom( bindingContext.ModelType.GetTypeInfo())) { var postedFiles = await GetFormFilesAsync(bindingContext); var value = ModelBindingHelper.ConvertValuesToCollectionType(bindingContext.ModelType, postedFiles); return(new ModelBindingResult(value, bindingContext.ModelName, isModelSet: value != null)); } return(null); }
public virtual async Task <ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext); if (!await bindingContext.ValueProvider.ContainsPrefixAsync(bindingContext.ModelName)) { return(null); } var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName); var bindCollectionTask = valueProviderResult != null? BindSimpleCollection(bindingContext, valueProviderResult.RawValue, valueProviderResult.Culture) : BindComplexCollection(bindingContext); var boundCollection = await bindCollectionTask; var model = GetModel(boundCollection); return(new ModelBindingResult(model, bindingContext.ModelName, isModelSet: true)); }
// 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 for testing. internal async Task <CollectionResult> BindSimpleCollection( ModelBindingContext bindingContext, ValueProviderResult values) { var boundCollection = new List <TElement>(); var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider; var elementMetadata = metadataProvider.GetMetadataForType(typeof(TElement)); var innerBindingContext = ModelBindingContext.CreateChildBindingContext( bindingContext, elementMetadata, fieldName: bindingContext.FieldName, modelName: bindingContext.ModelName, model: null); foreach (var value in values) { innerBindingContext.ValueProvider = new CompositeValueProvider { // our temporary provider goes at the front of the list new ElementalValueProvider(bindingContext.ModelName, value, values.Culture), bindingContext.ValueProvider }; object boundValue = null; var result = await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(innerBindingContext); if (result != null && result.IsModelSet) { boundValue = result.Model; boundCollection.Add(ModelBindingHelper.CastOrDefault <TElement>(boundValue)); } } return(new CollectionResult { Model = 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 async Task <IEnumerable <TElement> > BindSimpleCollection(ModelBindingContext bindingContext, object rawValue, CultureInfo culture) { if (rawValue == null) { return(null); // nothing to do } var boundCollection = new List <TElement>(); var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider; var elementMetadata = metadataProvider.GetMetadataForType(typeof(TElement)); var rawValueArray = RawValueToObjectArray(rawValue); foreach (var rawValueElement in rawValueArray) { var innerBindingContext = ModelBindingContext.GetChildModelBindingContext( bindingContext, bindingContext.ModelName, elementMetadata); innerBindingContext.ValueProvider = new CompositeValueProvider { // our temporary provider goes at the front of the list new ElementalValueProvider(bindingContext.ModelName, rawValueElement, culture), bindingContext.ValueProvider }; object boundValue = null; var result = await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(innerBindingContext); if (result != null) { boundValue = result.Model; } boundCollection.Add(ModelBindingHelper.CastOrDefault <TElement>(boundValue)); } return(boundCollection); }
private async Task <ModelBindingResult> BindModelCoreAsync(ModelBindingContext bindingContext) { object value; if (bindingContext.ModelType == typeof(IFormFile)) { var postedFiles = await GetFormFilesAsync(bindingContext); value = postedFiles.FirstOrDefault(); } else if (typeof(IEnumerable <IFormFile>).IsAssignableFrom(bindingContext.ModelType)) { var postedFiles = await GetFormFilesAsync(bindingContext); value = ModelBindingHelper.ConvertValuesToCollectionType(bindingContext.ModelType, postedFiles); } else { // This binder does not support the requested type. Debug.Fail("We shouldn't be called without a matching type."); return(ModelBindingResult.NoResult); } if (value == null) { return(ModelBindingResult.Failed(bindingContext.ModelName)); } else { bindingContext.ValidationState.Add(value, new ValidationStateEntry() { SuppressValidation = true }); bindingContext.ModelState.SetModelValue( bindingContext.ModelName, rawValue: null, attemptedValue: null); return(ModelBindingResult.Success(bindingContext.ModelName, value)); } }
public async Task <bool> BindModelAsync(ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext); if (!ValueProviderResult.CanConvertFromString(bindingContext.ModelType)) { // this type cannot be converted return(false); } var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName); if (valueProviderResult == null) { return(false); // no entry } object newModel; bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); try { newModel = valueProviderResult.ConvertTo(bindingContext.ModelType); ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref newModel); bindingContext.Model = newModel; } catch (Exception ex) { if (IsFormatException(ex)) { // there was a type conversion failure bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex.Message); } else { bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex); } } return(true); }
public async Task <ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) { var valueProviderResult = await GetCompatibleValueProviderResult(bindingContext); if (valueProviderResult == null) { // conversion would have failed return(null); } bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); var model = valueProviderResult.RawValue; ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref model); // We do not need to set an explict ModelValidationNode since CompositeModelBinder does that automatically. return(new ModelBindingResult( model, bindingContext.ModelName, isModelSet: true)); }
/// <inheritdoc /> public Task <ModelBindingResult> BindModelAsync([NotNull] ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext); if (!CanBindType(bindingContext.ModelMetadata)) { return(ModelBindingResult.NoResultAsync); } var mutableObjectBinderContext = new MutableObjectBinderContext() { ModelBindingContext = bindingContext, PropertyMetadata = GetMetadataForProperties(bindingContext).ToArray(), }; if (!(CanCreateModel(mutableObjectBinderContext))) { return(ModelBindingResult.NoResultAsync); } return(BindModelCoreAsync(bindingContext, mutableObjectBinderContext)); }
public async Task <ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext.ModelType != typeof(ComplexModelDto)) { return(null); } ModelBindingHelper.ValidateBindingContext(bindingContext, typeof(ComplexModelDto), allowNullModel: false); var dto = (ComplexModelDto)bindingContext.Model; foreach (var propertyMetadata in dto.PropertyMetadata) { var propertyModelName = ModelNames.CreatePropertyModelName( bindingContext.ModelName, propertyMetadata.BinderModelName ?? propertyMetadata.PropertyName); var propertyBindingContext = ModelBindingContext.GetChildModelBindingContext( bindingContext, propertyModelName, propertyMetadata); var modelBindingResult = await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(propertyBindingContext); if (modelBindingResult == null) { // Could not bind. Add a result so MutableObjectModelBinder will check for [DefaultValue]. dto.Results[propertyMetadata] = new ModelBindingResult(model: null, key: propertyModelName, isModelSet: false); } else { dto.Results[propertyMetadata] = modelBindingResult; } } return(new ModelBindingResult(dto, bindingContext.ModelName, isModelSet: true)); }
/// <inheritdoc /> public virtual async Task <ModelBindingResult> BindModelAsync([NotNull] ModelBindingContext bindingContext) { ModelBindingHelper.ValidateBindingContext(bindingContext); if (!CanBindType(bindingContext.ModelMetadata)) { return(null); } var mutableObjectBinderContext = new MutableObjectBinderContext() { ModelBindingContext = bindingContext, PropertyMetadata = GetMetadataForProperties(bindingContext).ToArray(), }; if (!(await CanCreateModel(mutableObjectBinderContext))) { return(null); } // Create model first (if necessary) to avoid reporting errors about properties when activation fails. var model = GetModel(bindingContext); var results = await BindPropertiesAsync(bindingContext, mutableObjectBinderContext.PropertyMetadata); var validationNode = new ModelValidationNode( bindingContext.ModelName, bindingContext.ModelMetadata, model); // Post-processing e.g. property setters and hooking up validation. bindingContext.Model = model; ProcessResults(bindingContext, results, validationNode); return(new ModelBindingResult( model, bindingContext.ModelName, isModelSet: true, validationNode: validationNode)); }