Example #1
0
        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 virtual async Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
        {
            ModelBindingHelper.ValidateBindingContext(bindingContext);
            if (!CanBindType(bindingContext.ModelType))
            {
                return null;
            }

            var mutableObjectBinderContext = new MutableObjectBinderContext()
            {
                ModelBindingContext = bindingContext,
                PropertyMetadata = GetMetadataForProperties(bindingContext),
            };

            if (!(await CanCreateModel(mutableObjectBinderContext)))
            {
                return null;
            }

            EnsureModel(bindingContext);
            var result = await CreateAndPopulateDto(bindingContext, mutableObjectBinderContext.PropertyMetadata);

            // post-processing, e.g. property setters and hooking up validation
            ProcessDto(bindingContext, (ComplexModelDto)result.Model);
            return new ModelBindingResult(
                bindingContext.Model,
                bindingContext.ModelName,
                isModelSet: true);
        }
Example #3
0
        public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType == typeof(DateTime) || bindingContext.ModelType == typeof(DateTime?))
            {
                var displayFormat = bindingContext.ModelMetadata.DisplayFormatString;

                //if (Controls.Global.UserInfo != null)
                {
                    displayFormat = AppSettings.DateFormat;//Controls.Global.UserInfo.FormatDate;
                }

                var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

                if (!string.IsNullOrEmpty(displayFormat) && value != null && !string.IsNullOrEmpty(value.FirstOrDefault()))
                {
                    DateTime date;
                    //displayFormat = displayFormat.Replace("{0:", string.Empty).Replace("}", string.Empty);
                    // use the format specified in the DisplayFormat attribute to parse the date
                    if (DateTime.TryParseExact(value.FirstOrDefault(), displayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
                    {
                        bindingContext.Model = date;
                        return Task.FromResult(new ModelBindingResult());
                    }
                    else
                    {
                        bindingContext.ModelState.AddModelError(
                            bindingContext.ModelName,
                            string.Format("{0} is an invalid date format", value.FirstOrDefault())
                        );
                    }
                }
            }

            return Task.FromResult(new ModelBindingResult());
        }
        public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
        {
            if(bindingContext.ModelType != typeof(Currency))
            {
                return ModelBindingResult.NoResultAsync;
            }

            var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if(valueProviderResult == ValueProviderResult.None)
            {
                return ModelBindingResult.FailedAsync(bindingContext.ModelName);
            }

            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
            var value = valueProviderResult.FirstValue;
            if(string.IsNullOrEmpty(value))
            {
                return ModelBindingResult.FailedAsync(bindingContext.ModelName);
            }

            var model = (Currency)value;
            if(model == null)
            {
                return ModelBindingResult.FailedAsync(bindingContext.ModelName);
            }

            var validationNode = new ModelValidationNode(
                bindingContext.ModelName,
                bindingContext.ModelMetadata,
                model
            );

            return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model, validationNode);
        }
        private static Type GetEnumerableBinder(ModelBindingContext context)
        {
            var modelTypeArguments = GetGenericBinderTypeArgs(typeof(IEnumerable<>), context.ModelType);
            if (modelTypeArguments == null)
            {
                return null;
            }

            if (context.Model == null)
            {
                // GetCollectionBinder has already confirmed modelType is not compatible with ICollection<T>. Can a
                // List<T> (the default CollectionModelBinder type) instance be used instead of that exact type?
                // Likely this will succeed only if the property type is exactly IEnumerable<T>.
                var closedListType = typeof(List<>).MakeGenericType(modelTypeArguments);
                if (!context.ModelType.IsAssignableFrom(closedListType))
                {
                    return null;
                }
            }
            else
            {
                // A non-null instance must be updated in-place. For that the instance must also implement
                // ICollection<T>. For example an IEnumerable<T> property may have a List<T> default value.
                var closedCollectionType = typeof(ICollection<>).MakeGenericType(modelTypeArguments);
                if (!closedCollectionType.IsAssignableFrom(context.Model.GetType()))
                {
                    return null;
                }
            }

            return typeof(CollectionModelBinder<>).MakeGenericType(modelTypeArguments);
        }
        public async Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
        {
            var binderType = ResolveBinderType(bindingContext);
            if (binderType != null)
            {
                var binder = (IModelBinder)Activator.CreateInstance(binderType);

                var collectionBinder = binder as ICollectionModelBinder;
                if (collectionBinder != null &&
                    bindingContext.Model == null &&
                    !collectionBinder.CanCreateInstance(bindingContext.ModelType))
                {
                    // Able to resolve a binder type but need a new model instance and that binder cannot create it.
                    return null;
                }

                var result = await binder.BindModelAsync(bindingContext);
                var modelBindingResult = result != null ?
                    result :
                    new ModelBindingResult(model: null, key: bindingContext.ModelName, isModelSet: false);

                // Were able to resolve a binder type.
                // Always tell the model binding system to skip other model binders i.e. return non-null.
                return modelBindingResult;
            }

            return null;
        }
Example #7
0
        public async Task<bool> BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType == typeof(ComplexModelDto))
            {
                ModelBindingHelper.ValidateBindingContext(bindingContext,
                                                          typeof(ComplexModelDto),
                                                          allowNullModel: false);

                var dto = (ComplexModelDto)bindingContext.Model;
                foreach (var propertyMetadata in dto.PropertyMetadata)
                {
                    var propertyBindingContext = new ModelBindingContext(bindingContext)
                    {
                        ModelMetadata = propertyMetadata,
                        ModelName = ModelBindingHelper.CreatePropertyModelName(bindingContext.ModelName,
                                                                               propertyMetadata.PropertyName)
                    };

                    // bind and propagate the values
                    // If we can't bind, then leave the result missing (don't add a null).
                    if (await bindingContext.ModelBinder.BindModelAsync(propertyBindingContext))
                    {
                        var result = new ComplexModelDtoResult(propertyBindingContext.Model,
                                                               propertyBindingContext.ValidationNode);
                        dto.Results[propertyMetadata] = result;
                    }
                }

                return true;
            }

            return false;
        }
Example #8
0
        private async Task<List<IFormFile>> GetFormFilesAsync(ModelBindingContext bindingContext)
        {
            var request = bindingContext.OperationBindingContext.HttpContext.Request;
            var postedFiles = new List<IFormFile>();
            if (request.HasFormContentType)
            {
                var form = await request.ReadFormAsync();

                foreach (var file in form.Files)
                {
                    ContentDispositionHeaderValue parsedContentDisposition;
                    ContentDispositionHeaderValue.TryParse(file.ContentDisposition, out parsedContentDisposition);

                    // If there is an <input type="file" ... /> in the form and is left blank.
                    if (parsedContentDisposition == null ||
                        (file.Length == 0 &&
                         string.IsNullOrEmpty(HeaderUtilities.RemoveQuotes(parsedContentDisposition.FileName))))
                    {
                        continue;
                    }

                    var modelName = HeaderUtilities.RemoveQuotes(parsedContentDisposition.Name);
                    if (modelName.Equals(bindingContext.ModelName, StringComparison.OrdinalIgnoreCase))
                    {
                        postedFiles.Add(file);
                    }
                }
            }

            return postedFiles;
        }
        public async Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext.BinderType == null)
            {
                // Return null so that we are able to continue with the default set of model binders,
                // if there is no specific model binder provided.
                return null;
            }

            var requestServices = bindingContext.OperationBindingContext.HttpContext.RequestServices;
            var createFactory = _typeActivatorCache.GetOrAdd(bindingContext.BinderType, _createFactory);
            var instance = createFactory(requestServices, arguments: null);

            var modelBinder = instance as IModelBinder;
            if (modelBinder == null)
            {
                throw new InvalidOperationException(
                    Resources.FormatBinderType_MustBeIModelBinder(
                        bindingContext.BinderType.FullName,
                        typeof(IModelBinder).FullName));
            }

            var result = await modelBinder.BindModelAsync(bindingContext);

            var modelBindingResult = result != null ?
                new ModelBindingResult(result.Model, result.Key, result.IsModelSet, result.ValidationNode) :
                new ModelBindingResult(model: null, key: bindingContext.ModelName, isModelSet: false);

            // A model binder was specified by metadata and this binder handles all such cases.
            // Always tell the model binding system to skip other model binders i.e. return non-null.
            return modelBindingResult;
        }
Example #10
0
        public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
        {
            // This method is optimized to use cached tasks when possible and avoid allocating
            // using Task.FromResult. If you need to make changes of this nature, profile
            // allocations afterwards and look for Task<ModelBindingResult>.

            var binderType = ResolveBinderType(bindingContext);
            if (binderType == null)
            {
                return ModelBindingResult.NoResultAsync;
            }

            var binder = (IModelBinder)Activator.CreateInstance(binderType);

            var collectionBinder = binder as ICollectionModelBinder;
            if (collectionBinder != null &&
                bindingContext.Model == null &&
                !collectionBinder.CanCreateInstance(bindingContext.ModelType))
            {
                // Able to resolve a binder type but need a new model instance and that binder cannot create it.
                return ModelBindingResult.NoResultAsync;
            }

            return BindModelCoreAsync(bindingContext, binder);
        }
        private async Task<ModelBindingResult> BindModelCoreAsync(ModelBindingContext bindingContext)
        {
            var requestServices = bindingContext.OperationBindingContext.HttpContext.RequestServices;
            var createFactory = _typeActivatorCache.GetOrAdd(bindingContext.BinderType, _createFactory);
            var instance = createFactory(requestServices, arguments: null);

            var modelBinder = instance as IModelBinder;
            if (modelBinder == null)
            {
                throw new InvalidOperationException(
                    Resources.FormatBinderType_MustBeIModelBinder(
                        bindingContext.BinderType.FullName,
                        typeof(IModelBinder).FullName));
            }

            var result = await modelBinder.BindModelAsync(bindingContext);

            var modelBindingResult = result != ModelBindingResult.NoResult ?
                result :
                ModelBindingResult.Failed(bindingContext.ModelName);

            // A model binder was specified by metadata and this binder handles all such cases.
            // Always tell the model binding system to skip other model binders i.e. return non-null.
            return modelBindingResult;
        }
        public async Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
        {
            ModelBindingHelper.ValidateBindingContext(bindingContext);

            if (!TypeHelper.HasStringConverter(bindingContext.ModelType))
            {
                // 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);
                return new ModelBindingResult(newModel, bindingContext.ModelName, isModelSet: true);
            }
            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);
        }
        public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType == typeof(HttpRequestMessage))
            {
                var model = bindingContext.OperationBindingContext.HttpContext.GetHttpRequestMessage();
                return Task.FromResult(new ModelBindingResult(model, bindingContext.ModelName, isModelSet: true));
            }

            return Task.FromResult<ModelBindingResult>(null);
        }
Example #14
0
        private static Type ResolveBinderType(ModelBindingContext context)
        {
            var modelType = context.ModelType;

            return GetArrayBinder(modelType) ??
                GetCollectionBinder(modelType) ??
                GetDictionaryBinder(modelType) ??
                GetEnumerableBinder(context) ??
                GetKeyValuePairBinder(modelType);
        }
        /// <inheritdoc />
        public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType == typeof(CancellationToken))
            {
                var model = bindingContext.OperationBindingContext.HttpContext.RequestAborted;
                return Task.FromResult(new ModelBindingResult(model, bindingContext.ModelName, isModelSet: true));
            }

            return Task.FromResult<ModelBindingResult>(null);
        }
Example #16
0
 public object BindModel(ActionContext actionContext, ModelBindingContext bindingContext)
 {
     var cart = actionContext.HttpContext.Session[SessionKey];
     if (cart == null)
     {
         cart = Uitilties.ObjectToByteArray(new Cart());
         actionContext.HttpContext.Session[SessionKey] = cart;
     }
     return cart;
 }
        /// <inheritdoc />
        public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType == typeof(CancellationToken))
            {
                var model = bindingContext.OperationBindingContext.HttpContext.RequestAborted;
                return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model);
            }

            return ModelBindingResult.NoResultAsync;
        }
        /// <inheritdoc />
        public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType == typeof(HttpRequestMessage))
            {
                var model = bindingContext.OperationBindingContext.HttpContext.GetHttpRequestMessage();
                bindingContext.ValidationState.Add(model, new ValidationStateEntry() { SuppressValidation = true });
                return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model);
            }

            return ModelBindingResult.NoResultAsync;
        }
Example #19
0
        /// <inheritdoc />
        public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
        {
            // This method is optimized to use cached tasks when possible and avoid allocating
            // using Task.FromResult. If you need to make changes of this nature, profile
            // allocations afterwards and look for Task<ModelBindingResult>.

            var allowedBindingSource = bindingContext.BindingSource;
            if (allowedBindingSource == null ||
                !allowedBindingSource.CanAcceptDataFrom(BindingSource.Header))
            {
                // Headers are opt-in. This model either didn't specify [FromHeader] or specified something
                // incompatible so let other binders run.
                return ModelBindingResult.NoResultAsync;
            }

            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.FieldName;
            object model = null;
            if (bindingContext.ModelType == typeof(string))
            {
                string value = request.Headers[headerName];
                if (value != null)
                {
                    model = value;
                }
            }
            else if (typeof(IEnumerable<string>).IsAssignableFrom(bindingContext.ModelType))
            {
                var values = request.Headers.GetCommaSeparatedValues(headerName);
                if (values.Length > 0)
                {
                    model = ModelBindingHelper.ConvertValuesToCollectionType(
                        bindingContext.ModelType,
                        values);
                }
            }

            if (model == null)
            {
                return ModelBindingResult.FailedAsync(bindingContext.ModelName);
            }
            else
            {
                bindingContext.ModelState.SetModelValue(
                    bindingContext.ModelName,
                    request.Headers.GetCommaSeparatedValues(headerName),
                    request.Headers[headerName]);

                return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model);
            }
        }
Example #20
0
        public Task<bool> BindModelAsync(ModelBindingContext bindingContext)
        {
            var binderType = ResolveBinderType(bindingContext.ModelType);
            if (binderType != null)
            {
                var binder = (IModelBinder)_activator.CreateInstance(_serviceProvider, binderType);
                return binder.BindModelAsync(bindingContext);
            }

            return Task.FromResult(false);
        }
Example #21
0
 // copies certain values that won't change between parent and child objects,
 // e.g. ValueProvider, ModelState
 public ModelBindingContext(ModelBindingContext bindingContext)
 {
     if (bindingContext != null)
     {
         ModelState = bindingContext.ModelState;
         ValueProvider = bindingContext.ValueProvider;
         MetadataProvider = bindingContext.MetadataProvider;
         ModelBinder = bindingContext.ModelBinder;
         ValidatorProviders = bindingContext.ValidatorProviders;
         HttpContext = bindingContext.HttpContext;
     }
 }
 public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
 {
     if (bindingContext.ModelType == typeof(IUser))
     {
         var model = bindingContext.OperationBindingContext.HttpContext.User as UserPrincipal;
         if (model != null)
             return Task.FromResult(ModelBindingResult.Success(bindingContext.ModelName, model.User));
         else
             return Task.FromResult(ModelBindingResult.Failed(bindingContext.ModelName));
     }
     return Task.FromResult(ModelBindingResult.NoResult);
 }
        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)
            {
                // no entry
                return null;
            }

            object newModel;
            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
            try
            {
                newModel = valueProviderResult.ConvertTo(bindingContext.ModelType);
                ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref 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;
                }

                // Include a ModelValidationNode if binding succeeded.
                var validationNode = isModelSet ?
                    new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, newModel) :
                    null;

                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);
        }
Example #24
0
        private async Task<ModelBindingResult> BindModelCoreAsync(ModelBindingContext bindingContext, IModelBinder binder)
        {
            Debug.Assert(binder != null);

            var result = await binder.BindModelAsync(bindingContext);
            var modelBindingResult = result != ModelBindingResult.NoResult ?
                result :
                ModelBindingResult.Failed(bindingContext.ModelName);

            // Were able to resolve a binder type.
            // Always tell the model binding system to skip other model binders.
            return modelBindingResult;
        }
Example #25
0
        public void BindAttribute_Include(string property, bool isIncluded)
        {
            // Arrange
            var bind = new BindAttribute(new string[] { "UserName", "FirstName", "LastName, MiddleName,  ,foo,bar " });

            var context = new ModelBindingContext();

            // Act
            var predicate = bind.PropertyFilter;

            // Assert
            Assert.Equal(isIncluded, predicate(context, property));
        }
        protected override Task<ModelBindingResult> BindModelCoreAsync(ModelBindingContext bindingContext)
        {
            var attributes = ((DefaultModelMetadata)bindingContext.ModelMetadata).Attributes;
            var metadata = attributes.OfType<FromTestAttribute>().First();
            var model = metadata.Value;
            if (!IsSimpleType(bindingContext.ModelType))
            {
                model = Activator.CreateInstance(bindingContext.ModelType);
                return Task.FromResult(new ModelBindingResult(model, bindingContext.ModelName, true));
            }

            return Task.FromResult(new ModelBindingResult(null, bindingContext.ModelName, false));
        }
        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);
        }
Example #28
0
        /// <inheritdoc />
        public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }

            // This method is optimized to use cached tasks when possible and avoid allocating
            // using Task.FromResult. If you need to make changes of this nature, profile
            // allocations afterwards and look for Task<ModelBindingResult>.

            // Check if this binder applies.
            if (bindingContext.ModelType != typeof(byte[]))
            {
                return ModelBindingResult.NoResultAsync;
            }

            // Check for missing data case 1: There was no <input ... /> element containing this data.
            var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if (valueProviderResult == ValueProviderResult.None)
            {
                return ModelBindingResult.FailedAsync(bindingContext.ModelName);
            }

            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);

            // Check for missing data case 2: There was an <input ... /> element but it was left blank.
            var value = valueProviderResult.FirstValue;
            if (string.IsNullOrEmpty(value))
            {
                return ModelBindingResult.FailedAsync(bindingContext.ModelName);
            }

            try
            {
                var model = Convert.FromBase64String(value);
                return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model);
            }
            catch (Exception exception)
            {
                bindingContext.ModelState.TryAddModelError(
                    bindingContext.ModelName,
                    exception,
                    bindingContext.ModelMetadata);
            }

            // Matched the type (byte[]) only this binder supports. As in missing data cases, always tell the model
            // binding system to skip other model binders i.e. return non-null.
            return ModelBindingResult.FailedAsync(bindingContext.ModelName);
        }
        public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
        {
            // This method is optimized to use cached tasks when possible and avoid allocating
            // using Task.FromResult. If you need to make changes of this nature, profile
            // allocations afterwards and look for Task<ModelBindingResult>.

            if (bindingContext.BinderType == null)
            {
                // Return NoResult so that we are able to continue with the default set of model binders,
                // if there is no specific model binder provided.
                return ModelBindingResult.NoResultAsync;
            }

            return BindModelCoreAsync(bindingContext);
        }
            public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
            {
                if (typeof(OrderStatus).IsAssignableFrom(bindingContext.ModelType))
                {
                    var request = bindingContext.OperationBindingContext.HttpContext.Request;

                    // Doing something slightly different here to make sure we don't get accidentally bound
                    // by the type converter binder.
                    OrderStatus model;
                    var isModelSet = Enum.TryParse<OrderStatus>("Status" + request.Query.Get("status"), out model);
                    return Task.FromResult(new ModelBindingResult(model, "status", isModelSet));
                }

                return Task.FromResult<ModelBindingResult>(null);
            }
Example #31
0
 protected override Task <ModelBindingResult> BindModelCoreAsync([NotNull] ModelBindingContext bindingContext)
 {
     WasBindModelCoreCalled = true;
     return(Task.FromResult(
                new ModelBindingResult(model: null, key: bindingContext.ModelName, isModelSet: _isModelSet)));
 }
Example #32
0
        /// <inheritdoc />
        public override async Task <ModelBindingResult> BindModelAsync([NotNull] ModelBindingContext bindingContext)
        {
            var result = await base.BindModelAsync(bindingContext);

            if (result == null || !result.IsModelSet)
            {
                // No match for the prefix at all.
                return(result);
            }

            Debug.Assert(result.Model != null);
            var model = (IDictionary <TKey, TValue>)result.Model;

            if (model.Count != 0)
            {
                // ICollection<KeyValuePair<TKey, TValue>> approach was successful.
                return(result);
            }

            var enumerableValueProvider = bindingContext.ValueProvider as IEnumerableValueProvider;

            if (enumerableValueProvider == null)
            {
                // No IEnumerableValueProvider available for the fallback approach. For example the user may have
                // replaced the ValueProvider with something other than a CompositeValueProvider.
                return(result);
            }

            // Attempt to bind dictionary from a set of prefix[key]=value entries. Get the short and long keys first.
            var keys = await enumerableValueProvider.GetKeysFromPrefixAsync(bindingContext.ModelName);

            if (!keys.Any())
            {
                // No entries with the expected keys.
                return(result);
            }

            // Update the existing successful but empty ModelBindingResult.
            var metadataProvider    = bindingContext.OperationBindingContext.MetadataProvider;
            var valueMetadata       = metadataProvider.GetMetadataForType(typeof(TValue));
            var valueBindingContext = ModelBindingContext.GetChildModelBindingContext(
                bindingContext,
                bindingContext.ModelName,
                valueMetadata);

            var modelBinder    = bindingContext.OperationBindingContext.ModelBinder;
            var validationNode = result.ValidationNode;

            foreach (var key in keys)
            {
                var dictionaryKey = ConvertFromString(key.Key);
                valueBindingContext.ModelName = key.Value;

                var valueResult = await modelBinder.BindModelAsync(valueBindingContext);

                // Always add an entry to the dictionary but validate only if binding was successful.
                model[dictionaryKey] = ModelBindingHelper.CastOrDefault <TValue>(valueResult?.Model);
                if (valueResult != null && valueResult.IsModelSet)
                {
                    validationNode.ChildNodes.Add(valueResult.ValidationNode);
                }
            }

            return(result);
        }