Esempio n. 1
0
        internal void ProcessComplexModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext, ComplexModel complexModel)
        {
            HashSet <string> requiredProperties;
            HashSet <string> skipProperties;

            GetRequiredPropertiesCollection(bindingContext.ModelType, out requiredProperties, out skipProperties);

            // Are all of the required fields accounted for?
            HashSet <string> missingRequiredProperties = new HashSet <string>(requiredProperties);

            missingRequiredProperties.ExceptWith(complexModel.Results.Select(r => r.Key.PropertyName));
            string missingPropertyName = missingRequiredProperties.FirstOrDefault();

            if (missingPropertyName != null)
            {
                string fullPropertyKey = ModelBinderUtil.CreatePropertyModelName(bindingContext.ModelName, missingPropertyName);
                throw Error.BindingBehavior_ValueNotFound(fullPropertyKey);
            }

            // for each property that was bound, call the setter, recording exceptions as necessary
            foreach (var entry in complexModel.Results)
            {
                ModelMetadata propertyMetadata = entry.Key;

                ComplexModelResult complexModelResult = entry.Value;
                if (complexModelResult != null)
                {
                    SetProperty(modelBindingExecutionContext, bindingContext, propertyMetadata, complexModelResult);
                    bindingContext.ValidationNode.ChildNodes.Add(complexModelResult.ValidationNode);
                }
            }
        }
Esempio n. 2
0
        private void ValidateProperties(ModelBindingExecutionContext modelBindingExecutionContext)
        {
            // Based off CompositeModelValidator.
            ModelStateDictionary modelState = modelBindingExecutionContext.ModelState;

            // DevDiv Bugs #227802 - Caching problem in ModelMetadata requires us to manually regenerate
            // the ModelMetadata.
            object        model           = ModelMetadata.Model;
            ModelMetadata updatedMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, ModelMetadata.ModelType);

            foreach (ModelMetadata propertyMetadata in updatedMetadata.Properties)
            {
                // Only want to add errors to ModelState if something doesn't already exist for the property node,
                // else we could end up with duplicate or irrelevant error messages.
                string propertyKeyRoot = ModelBinderUtil.CreatePropertyModelName(ModelStateKey, propertyMetadata.PropertyName);

                if (modelState.IsValidField(propertyKeyRoot))
                {
                    foreach (ModelValidator propertyValidator in propertyMetadata.GetValidators(modelBindingExecutionContext))
                    {
                        foreach (ModelValidationResult propertyResult in propertyValidator.Validate(model))
                        {
                            string thisErrorKey = ModelBinderUtil.CreatePropertyModelName(propertyKeyRoot, propertyResult.MemberName);
                            modelState.AddModelError(thisErrorKey, propertyResult.Message);
                        }
                    }
                }
            }
        }
Esempio n. 3
0
        public override IModelBinder GetBinder(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            Type[] typeArguments = null;
            if (ModelType.IsInterface)
            {
                Type matchingClosedInterface = TypeHelpers.ExtractGenericInterface(bindingContext.ModelType, ModelType);
                if (matchingClosedInterface != null)
                {
                    typeArguments = matchingClosedInterface.GetGenericArguments();
                }
            }
            else
            {
                typeArguments = TypeHelpers.GetTypeArgumentsIfMatch(bindingContext.ModelType, ModelType);
            }

            if (typeArguments != null)
            {
                if (SuppressPrefixCheck || bindingContext.UnvalidatedValueProvider.ContainsPrefix(bindingContext.ModelName))
                {
                    return(_modelBinderFactory(typeArguments));
                }
            }

            return(null);
        }
Esempio n. 4
0
            public bool BindModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
            {
                ModelBinderUtil.ValidateBindingContext(bindingContext);
                ValueProviderResult vpResult = bindingContext.UnvalidatedValueProvider.GetValue(bindingContext.ModelName);

                // case 1: there was no <input ... /> element containing this data
                if (vpResult == null)
                {
                    return(false);
                }

                string base64string = (string)vpResult.ConvertTo(typeof(string));

                // case 2: there was an <input ... /> element but it was left blank
                if (String.IsNullOrEmpty(base64string))
                {
                    return(false);
                }

                // Future proofing. If the byte array is actually an instance of System.Data.Linq.Binary
                // then we need to remove these quotes put in place by the ToString() method.
                string realValue = base64string.Replace("\"", String.Empty);

                try {
                    bindingContext.Model = ConvertByteArray(Convert.FromBase64String(realValue));
                    return(true);
                }
                catch {
                    // corrupt data - just ignore
                    return(false);
                }
            }
Esempio n. 5
0
        // Used when the ValueProvider contains the collection to be bound as multiple elements, e.g. foo[0], foo[1].
        private static List <TElement> BindComplexCollection(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
        {
            string indexPropertyName           = ModelBinderUtil.CreatePropertyModelName(bindingContext.ModelName, "index");
            ValueProviderResult  vpResultIndex = bindingContext.UnvalidatedValueProvider.GetValue(indexPropertyName);
            IEnumerable <string> indexNames    = CollectionModelBinderUtil.GetIndexNamesFromValueProviderResult(vpResultIndex);

            return(BindComplexCollectionFromIndexes(modelBindingExecutionContext, bindingContext, indexNames));
        }
        public override IModelBinder GetBinder(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            if (bindingContext.UnvalidatedValueProvider.ContainsPrefix(bindingContext.ModelName))
            {
                return(CollectionModelBinderUtil.GetGenericBinder(typeof(IDictionary <,>), typeof(Dictionary <,>), typeof(DictionaryModelBinder <,>), bindingContext.ModelMetadata));
            }
            else
            {
                return(null);
            }
        }
        public override IModelBinder GetBinder(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            if (!bindingContext.ModelMetadata.IsReadOnly && bindingContext.ModelType.IsArray &&
                bindingContext.UnvalidatedValueProvider.ContainsPrefix(bindingContext.ModelName))
            {
                Type elementType = bindingContext.ModelType.GetElementType();
                return((IModelBinder)Activator.CreateInstance(typeof(ArrayModelBinder <>).MakeGenericType(elementType)));
            }

            return(null);
        }
Esempio n. 8
0
        public virtual bool BindModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            ValueProviderResult vpResult        = bindingContext.UnvalidatedValueProvider.GetValue(bindingContext.ModelName, skipValidation: !bindingContext.ValidateRequest);
            List <TElement>     boundCollection = (vpResult != null)
                ? BindSimpleCollection(modelBindingExecutionContext, bindingContext, vpResult.RawValue, vpResult.Culture)
                : BindComplexCollection(modelBindingExecutionContext, bindingContext);

            bool retVal = CreateOrReplaceCollection(modelBindingExecutionContext, bindingContext, boundCollection);

            return(retVal);
        }
Esempio n. 9
0
        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);
        }
        public override IModelBinder GetBinder(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            if (bindingContext.ModelType == ModelType)
            {
                if (SuppressPrefixCheck || bindingContext.UnvalidatedValueProvider.ContainsPrefix(bindingContext.ModelName))
                {
                    return(_modelBinderFactory());
                }
            }

            return(null);
        }
Esempio n. 11
0
        public virtual bool BindModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
        {
            // Recursive method - prevent stack overflow.
            RuntimeHelpers.EnsureSufficientExecutionStack();

            ModelBinderUtil.ValidateBindingContext(bindingContext);

            EnsureModel(modelBindingExecutionContext, bindingContext);
            IEnumerable <ModelMetadata> propertyMetadatas = GetMetadataForProperties(modelBindingExecutionContext, bindingContext);
            ComplexModel complexModel = CreateAndPopulateComplexModel(modelBindingExecutionContext, bindingContext, propertyMetadatas);

            // post-processing, e.g. property setters and hooking up validation
            ProcessComplexModel(modelBindingExecutionContext, bindingContext, complexModel);
            bindingContext.ValidationNode.ValidateAllProperties = true; // complex models require full validation
            return(true);
        }
        public bool BindModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext, typeof(KeyValuePair <TKey, TValue>), true /* allowNullModel */);

            TKey key;
            bool keyBindingSucceeded = KeyValuePairModelBinderUtil.TryBindStrongModel <TKey>(modelBindingExecutionContext, bindingContext, "key", MetadataProvider, out key);

            TValue value;
            bool   valueBindingSucceeded = KeyValuePairModelBinderUtil.TryBindStrongModel <TValue>(modelBindingExecutionContext, bindingContext, "value", MetadataProvider, out value);

            if (keyBindingSucceeded && valueBindingSucceeded)
            {
                bindingContext.Model = new KeyValuePair <TKey, TValue>(key, value);
            }
            return(keyBindingSucceeded || valueBindingSucceeded);
        }
        public override IModelBinder GetBinder(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            string keyFieldName   = ModelBinderUtil.CreatePropertyModelName(bindingContext.ModelName, "key");
            string valueFieldName = ModelBinderUtil.CreatePropertyModelName(bindingContext.ModelName, "value");

            if (bindingContext.UnvalidatedValueProvider.ContainsPrefix(keyFieldName) && bindingContext.UnvalidatedValueProvider.ContainsPrefix(valueFieldName))
            {
                return(ModelBinderUtil.GetPossibleBinderInstance(bindingContext.ModelType, typeof(KeyValuePair <,>) /* supported model type */, typeof(KeyValuePairModelBinder <,>) /* binder type */));
            }
            else
            {
                // 'key' or 'value' missing
                return(null);
            }
        }
        public override IModelBinder GetBinder(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            ValueProviderResult vpResult = bindingContext.UnvalidatedValueProvider.GetValue(bindingContext.ModelName, skipValidation: !bindingContext.ValidateRequest);

            if (vpResult == null)
            {
                return(null); // no value to convert
            }

            if (!TypeDescriptor.GetConverter(bindingContext.ModelType).CanConvertFrom(typeof(string)))
            {
                return(null); // this type cannot be converted
            }

            return(new TypeConverterModelBinder());
        }
Esempio n. 15
0
        private void ValidateThis(ModelBindingExecutionContext modelBindingExecutionContext, ModelValidationNode parentNode)
        {
            ModelStateDictionary modelState = modelBindingExecutionContext.ModelState;

            if (!modelState.IsValidField(ModelStateKey))
            {
                return; // short-circuit
            }

            object container = TryConvertContainerToMetadataType(parentNode);

            foreach (ModelValidator validator in ModelMetadata.GetValidators(modelBindingExecutionContext))
            {
                foreach (ModelValidationResult validationResult in validator.Validate(container))
                {
                    string trueModelStateKey = ModelBinderUtil.CreatePropertyModelName(ModelStateKey, validationResult.MemberName);
                    modelState.AddModelError(trueModelStateKey, validationResult.Message);
                }
            }
        }
Esempio n. 16
0
        public bool BindModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            ValueProviderResult vpResult = bindingContext.UnvalidatedValueProvider.GetValue(bindingContext.ModelName, skipValidation: !bindingContext.ValidateRequest);

            if (vpResult == null)
            {
                return(false); // no entry
            }

            object newModel;

            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, vpResult);
            try {
                newModel = vpResult.ConvertTo(bindingContext.ModelType);
            }
            catch (Exception ex) {
                if (IsFormatException(ex))
                {
                    // there was a type conversion failure
                    string errorString = ModelBinderErrorMessageProviders.TypeConversionErrorMessageProvider(modelBindingExecutionContext, bindingContext.ModelMetadata, vpResult.AttemptedValue);
                    if (errorString != null)
                    {
                        bindingContext.ModelState.AddModelError(bindingContext.ModelName, errorString);
                    }
                }
                else
                {
                    bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex);
                }
                return(false);
            }

            ModelBinderUtil.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref newModel);
            bindingContext.Model = newModel;
            return(true);
        }
Esempio n. 17
0
        // 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);
        }