public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext 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.ValueProvider.ContainsPrefix(bindingContext.ModelName))
                {
                    return _modelBinderFactory(typeArguments);
                }
            }

            return null;
        }
            public bool BindModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) {
                ModelBinderUtil.ValidateBindingContext(bindingContext);
                ValueProviderResult vpResult = bindingContext.ValueProvider.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;
                }
            }
示例#3
0
        public bool BindModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            ValueProviderResult vpResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            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 = ModelBinderConfig.TypeConversionErrorMessageProvider(controllerContext, 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;
        }
        public bool BindModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext, typeof(ComplexModelDto), false /* allowNullModel */);

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

                // bind and propagate the values
                IExtensibleModelBinder propertyBinder = bindingContext.ModelBinderProviders.GetBinder(controllerContext, propertyBindingContext);
                if (propertyBinder != null) {
                    if (propertyBinder.BindModel(controllerContext, propertyBindingContext)) {
                        dto.Results[propertyMetadata] = new ComplexModelDtoResult(propertyBindingContext.Model, propertyBindingContext.ValidationNode);
                    }
                    else {
                        dto.Results[propertyMetadata] = null;
                    }
                }
            }

            return true;
        }
 // copies certain values that won't change between parent and child objects,
 // e.g. ValueProvider, ModelState
 public ExtensibleModelBindingContext(ExtensibleModelBindingContext bindingContext) {
     if (bindingContext != null) {
         ModelBinderProviders = bindingContext.ModelBinderProviders;
         ModelState = bindingContext.ModelState;
         ValueProvider = bindingContext.ValueProvider;
     }
 }
 public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
 {
     return (from provider in _providers
             let binder = provider.GetBinder(controllerContext, bindingContext)
             where binder != null
             select binder).FirstOrDefault();
 }
        public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            if (bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) {
                return CollectionModelBinderUtil.GetGenericBinder(typeof(IDictionary<,>), typeof(Dictionary<,>), typeof(DictionaryModelBinder<,>), bindingContext.ModelMetadata);
            }
            else {
                return null;
            }
        }
        private ExtensibleModelBindingContext CreateNewBindingContext(ModelBindingContext oldBindingContext, string modelName) {
            ExtensibleModelBindingContext newBindingContext = new ExtensibleModelBindingContext() {
                ModelBinderProviders = Providers,
                ModelMetadata = oldBindingContext.ModelMetadata,
                ModelName = modelName,
                ModelState = oldBindingContext.ModelState,
                ValueProvider = oldBindingContext.ValueProvider
            };

            return newBindingContext;
        }
        public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

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

            return null;
        }
        private ComplexModelDto CreateAndPopulateDto(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext, IEnumerable<ModelMetadata> propertyMetadatas) {
            // create a DTO and call into the DTO binder
            ComplexModelDto originalDto = new ComplexModelDto(bindingContext.ModelMetadata, propertyMetadatas);
            ExtensibleModelBindingContext dtoBindingContext = new ExtensibleModelBindingContext(bindingContext) {
                ModelMetadata = MetadataProvider.GetMetadataForType(() => originalDto, typeof(ComplexModelDto)),
                ModelName = bindingContext.ModelName
            };

            IExtensibleModelBinder dtoBinder = bindingContext.ModelBinderProviders.GetRequiredBinder(controllerContext, dtoBindingContext);
            dtoBinder.BindModel(controllerContext, dtoBindingContext);
            return (ComplexModelDto)dtoBindingContext.Model;
        }
        public virtual bool BindModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            EnsureModel(controllerContext, bindingContext);
            IEnumerable<ModelMetadata> propertyMetadatas = GetMetadataForProperties(controllerContext, bindingContext);
            ComplexModelDto dto = CreateAndPopulateDto(controllerContext, bindingContext, propertyMetadatas);

            // post-processing, e.g. property setters and hooking up validation
            ProcessDto(controllerContext, bindingContext, dto);
            bindingContext.ValidationNode.ValidateAllProperties = true; // complex models require full validation
            return true;
        }
        public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

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

            return null;
        }
        public bool BindModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) {
            ValueProviderResult vpResult = GetCompatibleValueProviderResult(bindingContext);
            if (vpResult == null) {
                return false; // conversion would have failed
            }

            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, vpResult);
            object model = vpResult.RawValue;
            ModelBinderUtil.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref model);
            bindingContext.Model = model;

            return true;
        }
        public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            ValueProviderResult vpResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            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();
        }
        public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

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

            if (bindingContext.ValueProvider.ContainsPrefix(keyFieldName) && bindingContext.ValueProvider.ContainsPrefix(valueFieldName)) {
                return ModelBinderUtil.GetPossibleBinderInstance(bindingContext.ModelType, typeof(KeyValuePair<,>) /* supported model type */, typeof(KeyValuePairModelBinder<,>) /* binder type */);
            }
            else {
                // 'key' or 'value' missing
                return null;
            }
        }
        internal static ValueProviderResult GetCompatibleValueProviderResult(ExtensibleModelBindingContext bindingContext) {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            ValueProviderResult vpResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if (vpResult == null) {
                return null; // the value doesn't exist
            }

            if (!TypeHelpers.IsCompatibleObject(bindingContext.ModelType, vpResult.RawValue)) {
                return null; // value is of incompatible type
            }

            return vpResult;
        }
        public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) {
                // no values to bind
                return null;
            }

            if (bindingContext.ModelType == typeof(ComplexModelDto)) {
                // forbidden type - will cause a stack overflow if we try binding this type
                return null;
            }

            return new MutableObjectModelBinder();
        }
        public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

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

            return(null);
        }
 protected virtual object CreateModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
 {
     // If the Activator throws an exception, we want to propagate it back up the call stack, since the application
     // developer should know that this was an invalid type to try to bind to.
     return Activator.CreateInstance(bindingContext.ModelType);
 }
示例#20
0
        public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext 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.ValueProvider.ContainsPrefix(bindingContext.ModelName))
                {
                    return(_modelBinderFactory(typeArguments));
                }
            }

            return(null);
        }
 protected virtual void EnsureModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
 {
     if (bindingContext.Model == null)
     {
         bindingContext.ModelMetadata.Model = CreateModel(controllerContext, bindingContext);
     }
 }
        internal void ProcessDto(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext, ComplexModelDto dto)
        {
            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(dto.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 dto.Results)
            {
                ModelMetadata propertyMetadata = entry.Key;

                ComplexModelDtoResult dtoResult = entry.Value;
                if (dtoResult != null)
                {
                    SetProperty(controllerContext, bindingContext, propertyMetadata, dtoResult);
                    bindingContext.ValidationNode.ChildNodes.Add(dtoResult.ValidationNode);
                }
            }
        }
 public abstract IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext);
示例#24
0
        internal static List <TElement> BindComplexCollectionFromIndexes(ControllerContext controllerContext, ExtensibleModelBindingContext 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);
                ExtensibleModelBindingContext childBindingContext = new ExtensibleModelBindingContext(bindingContext)
                {
                    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(TElement)),
                    ModelName     = fullChildName
                };

                object boundValue = null;
                IExtensibleModelBinder childBinder = bindingContext.ModelBinderProviders.GetBinder(controllerContext, childBindingContext);
                if (childBinder != null)
                {
                    if (childBinder.BindModel(controllerContext, 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 static bool TryBindStrongModel <TModel>(ControllerContext controllerContext, ExtensibleModelBindingContext parentBindingContext, string propertyName, ModelMetadataProvider metadataProvider, out TModel model)
        {
            ExtensibleModelBindingContext propertyBindingContext = new ExtensibleModelBindingContext(parentBindingContext)
            {
                ModelMetadata = metadataProvider.GetMetadataForType(null, typeof(TModel)),
                ModelName     = ModelBinderUtil.CreatePropertyModelName(parentBindingContext.ModelName, propertyName)
            };

            IExtensibleModelBinder binder = parentBindingContext.ModelBinderProviders.GetBinder(controllerContext, propertyBindingContext);

            if (binder != null)
            {
                if (binder.BindModel(controllerContext, propertyBindingContext))
                {
                    object untypedModel = propertyBindingContext.Model;
                    model = ModelBinderUtil.CastOrDefault <TModel>(untypedModel);
                    parentBindingContext.ValidationNode.ChildNodes.Add(propertyBindingContext.ValidationNode);
                    return(true);
                }
            }

            model = default(TModel);
            return(false);
        }
示例#26
0
        public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            ValueProviderResult vpResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

            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());
        }
示例#27
0
 public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
 {
     return((TypeMatchModelBinder.GetCompatibleValueProviderResult(bindingContext) != null)
                ? new TypeMatchModelBinder()
                : null /* no match */);
 }
        internal IExtensibleModelBinder GetRequiredBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            IExtensibleModelBinder binder = GetBinder(controllerContext, bindingContext);

            if (binder == null)
            {
                throw Error.ModelBinderProviderCollection_BinderForTypeNotFound(bindingContext.ModelType);
            }
            return(binder);
        }
 public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
 {
     return((from provider in _providers
             let binder = provider.GetBinder(controllerContext, bindingContext)
                          where binder != null
                          select binder).FirstOrDefault());
 }
示例#30
0
 public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
 {
     return(_underlyingProvider.GetBinder(controllerContext, bindingContext));
 }
示例#31
0
 public abstract IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext);
        // Used when the ValueProvider contains the collection to be bound as multiple elements, e.g. foo[0], foo[1].
        private static List <TElement> BindComplexCollection(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            string indexPropertyName           = ModelBinderUtil.CreatePropertyModelName(bindingContext.ModelName, "index");
            ValueProviderResult  vpResultIndex = bindingContext.ValueProvider.GetValue(indexPropertyName);
            IEnumerable <string> indexNames    = CollectionModelBinderUtil.GetIndexNamesFromValueProviderResult(vpResultIndex);

            return(BindComplexCollectionFromIndexes(controllerContext, bindingContext, indexNames));
        }
        public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            if (bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName))
            {
                return(CollectionModelBinderUtil.GetGenericBinder(typeof(ICollection <>), typeof(List <>), typeof(CollectionModelBinder <>), bindingContext.ModelMetadata));
            }
            else
            {
                return(null);
            }
        }
        public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

            if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName))
            {
                // no values to bind
                return(null);
            }

            if (bindingContext.ModelType == typeof(ComplexModelDto))
            {
                // forbidden type - will cause a stack overflow if we try binding this type
                return(null);
            }

            return(new MutableObjectModelBinder());
        }
        protected virtual IEnumerable <ModelMetadata> GetMetadataForProperties(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            // keep a set of the required properties so that we can cross-reference bound properties later
            HashSet <string> requiredProperties;
            HashSet <string> skipProperties;

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

            return(from propertyMetadata in bindingContext.ModelMetadata.Properties
                   let propertyName = propertyMetadata.PropertyName
                                      let shouldUpdateProperty = requiredProperties.Contains(propertyName) || !skipProperties.Contains(propertyName)
                                                                 where shouldUpdateProperty && CanUpdateProperty(propertyMetadata)
                                                                 select propertyMetadata);
        }
示例#36
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(ControllerContext controllerContext, ExtensibleModelBindingContext 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)
            {
                ExtensibleModelBindingContext innerBindingContext = new ExtensibleModelBindingContext(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;
                IExtensibleModelBinder childBinder = bindingContext.ModelBinderProviders.GetBinder(controllerContext, innerBindingContext);
                if (childBinder != null)
                {
                    if (childBinder.BindModel(controllerContext, innerBindingContext))
                    {
                        boundValue = innerBindingContext.Model;
                        bindingContext.ValidationNode.ChildNodes.Add(innerBindingContext.ValidationNode);
                    }
                }
                boundCollection.Add(ModelBinderUtil.CastOrDefault <TElement>(boundValue));
            }

            return(boundCollection);
        }
        private ComplexModelDto CreateAndPopulateDto(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext, IEnumerable <ModelMetadata> propertyMetadatas)
        {
            // create a DTO and call into the DTO binder
            ComplexModelDto originalDto = new ComplexModelDto(bindingContext.ModelMetadata, propertyMetadatas);
            ExtensibleModelBindingContext dtoBindingContext = new ExtensibleModelBindingContext(bindingContext)
            {
                ModelMetadata = MetadataProvider.GetMetadataForType(() => originalDto, typeof(ComplexModelDto)),
                ModelName     = bindingContext.ModelName
            };

            IExtensibleModelBinder dtoBinder = bindingContext.ModelBinderProviders.GetRequiredBinder(controllerContext, dtoBindingContext);

            dtoBinder.BindModel(controllerContext, dtoBindingContext);
            return((ComplexModelDto)dtoBindingContext.Model);
        }
示例#38
0
 // Extensibility point that allows the bound collection to be manipulated or transformed before
 // being returned from the binder.
 protected virtual bool CreateOrReplaceCollection(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext, IList <TElement> newCollection)
 {
     CollectionModelBinderUtil.CreateOrReplaceCollection(bindingContext, newCollection, () => new List <TElement>());
     return(true);
 }
 protected virtual object CreateModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
 {
     // If the Activator throws an exception, we want to propagate it back up the call stack, since the application
     // developer should know that this was an invalid type to try to bind to.
     return(Activator.CreateInstance(bindingContext.ModelType));
 }
        protected virtual IEnumerable<ModelMetadata> GetMetadataForProperties(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            // keep a set of the required properties so that we can cross-reference bound properties later
            HashSet<string> requiredProperties;
            HashSet<string> skipProperties;
            GetRequiredPropertiesCollection(bindingContext.ModelType, out requiredProperties, out skipProperties);

            return from propertyMetadata in bindingContext.ModelMetadata.Properties
                   let propertyName = propertyMetadata.PropertyName
                   let shouldUpdateProperty = requiredProperties.Contains(propertyName) || !skipProperties.Contains(propertyName)
                   where shouldUpdateProperty && CanUpdateProperty(propertyMetadata)
                   select propertyMetadata;
        }
        protected virtual object CreateModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            // If the Activator throws an exception, we want to propagate it back up the call stack, since the application
            // developer should know that this was an invalid type to try to bind to.
            try
            {
                return Activator.CreateInstance(bindingContext.ModelType);
            }
            catch (MissingMethodException exception)
            {
                // Ensure thrown exception contains the type name.  Might be down a few levels.
                MissingMethodException replacementException =
                    ModelBinderUtil.EnsureDebuggableException(exception, bindingContext.ModelType.FullName);
                if (replacementException != null)
                {
                    throw replacementException;
                }

                throw;
            }
        }
        protected virtual void SetProperty(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext, ModelMetadata propertyMetadata, ComplexModelDtoResult dtoResult)
        {
            PropertyDescriptor propertyDescriptor = TypeDescriptorHelper.Get(bindingContext.ModelType).GetProperties().Find(propertyMetadata.PropertyName, true /* ignoreCase */);
            if (propertyDescriptor == null || propertyDescriptor.IsReadOnly)
            {
                return; // nothing to do
            }

            object value = dtoResult.Model ?? GetPropertyDefaultValue(propertyDescriptor);
            propertyMetadata.Model = value;

            // 'Required' validators need to run first so that we can provide useful error messages if
            // the property setters throw, e.g. if we're setting entity keys to null. See comments in
            // DefaultModelBinder.SetProperty() for more information.
            if (value == null)
            {
                string modelStateKey = dtoResult.ValidationNode.ModelStateKey;
                if (bindingContext.ModelState.IsValidField(modelStateKey))
                {
                    ModelValidator requiredValidator = ModelValidatorProviders.Providers.GetValidators(propertyMetadata, controllerContext).Where(v => v.IsRequired).FirstOrDefault();
                    if (requiredValidator != null)
                    {
                        foreach (ModelValidationResult validationResult in requiredValidator.Validate(bindingContext.Model))
                        {
                            bindingContext.ModelState.AddModelError(modelStateKey, validationResult.Message);
                        }
                    }
                }
            }

            if (value != null || TypeHelpers.TypeAllowsNullValue(propertyDescriptor.PropertyType))
            {
                try
                {
                    propertyDescriptor.SetValue(bindingContext.Model, value);
                }
                catch (Exception ex)
                {
                    // don't display a duplicate error message if a binding error has already occurred for this field
                    string modelStateKey = dtoResult.ValidationNode.ModelStateKey;
                    if (bindingContext.ModelState.IsValidField(modelStateKey))
                    {
                        bindingContext.ModelState.AddModelError(modelStateKey, ex);
                    }
                }
            }
            else
            {
                // trying to set a non-nullable value type to null, need to make sure there's a message
                string modelStateKey = dtoResult.ValidationNode.ModelStateKey;
                if (bindingContext.ModelState.IsValidField(modelStateKey))
                {
                    dtoResult.ValidationNode.Validated += CreateNullCheckFailedHandler(controllerContext, propertyMetadata, value);
                }
            }
        }
 public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
 {
     return (TypeMatchModelBinder.GetCompatibleValueProviderResult(bindingContext) != null)
                ? new TypeMatchModelBinder()
                : null /* no match */;
 }
        public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

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

            if (bindingContext.ValueProvider.ContainsPrefix(keyFieldName) && bindingContext.ValueProvider.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 IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            ModelBinderUtil.ValidateBindingContext(bindingContext);

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

            return(null);
        }
示例#46
0
 protected override bool CreateOrReplaceCollection(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext, IList <TElement> newCollection)
 {
     bindingContext.Model = newCollection.ToArray();
     return(true);
 }
 public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) {
     return _underlyingProvider.GetBinder(controllerContext, bindingContext);
 }
        protected virtual void SetProperty(
            ControllerContext controllerContext,
            ExtensibleModelBindingContext bindingContext,
            ModelMetadata propertyMetadata,
            ComplexModelDtoResult dtoResult
            )
        {
            PropertyDescriptor propertyDescriptor = TypeDescriptorHelper
                                                    .Get(bindingContext.ModelType)
                                                    .GetProperties()
                                                    .Find(
                propertyMetadata.PropertyName,
                true     /* ignoreCase */
                );

            if (propertyDescriptor == null || propertyDescriptor.IsReadOnly)
            {
                return; // nothing to do
            }

            object value = dtoResult.Model ?? GetPropertyDefaultValue(propertyDescriptor);

            propertyMetadata.Model = value;

            // 'Required' validators need to run first so that we can provide useful error messages if
            // the property setters throw, e.g. if we're setting entity keys to null. See comments in
            // DefaultModelBinder.SetProperty() for more information.
            if (value == null)
            {
                string modelStateKey = dtoResult.ValidationNode.ModelStateKey;
                if (bindingContext.ModelState.IsValidField(modelStateKey))
                {
                    ModelValidator requiredValidator = ModelValidatorProviders.Providers
                                                       .GetValidators(propertyMetadata, controllerContext)
                                                       .Where(v => v.IsRequired)
                                                       .FirstOrDefault();
                    if (requiredValidator != null)
                    {
                        foreach (
                            ModelValidationResult validationResult in requiredValidator.Validate(
                                bindingContext.Model
                                )
                            )
                        {
                            bindingContext.ModelState.AddModelError(
                                modelStateKey,
                                validationResult.Message
                                );
                        }
                    }
                }
            }

            if (value != null || TypeHelpers.TypeAllowsNullValue(propertyDescriptor.PropertyType))
            {
                try
                {
                    propertyDescriptor.SetValue(bindingContext.Model, value);
                }
                catch (Exception ex)
                {
                    // don't display a duplicate error message if a binding error has already occurred for this field
                    string modelStateKey = dtoResult.ValidationNode.ModelStateKey;
                    if (bindingContext.ModelState.IsValidField(modelStateKey))
                    {
                        bindingContext.ModelState.AddModelError(modelStateKey, ex);
                    }
                }
            }
            else
            {
                // trying to set a non-nullable value type to null, need to make sure there's a message
                string modelStateKey = dtoResult.ValidationNode.ModelStateKey;
                if (bindingContext.ModelState.IsValidField(modelStateKey))
                {
                    dtoResult.ValidationNode.Validated += CreateNullCheckFailedHandler(
                        controllerContext,
                        propertyMetadata,
                        value
                        );
                }
            }
        }
示例#49
0
 protected override bool CreateOrReplaceCollection(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext, IList <KeyValuePair <TKey, TValue> > newCollection)
 {
     CollectionModelBinderUtil.CreateOrReplaceDictionary(bindingContext, newCollection, () => new Dictionary <TKey, TValue>());
     return(true);
 }