private static bool TryGetProviderFromAttributes(Type modelType, out ModelBinderProvider provider)
        {
            ExtensibleModelBinderAttribute attr = TypeDescriptorHelper.Get(modelType).GetAttributes().OfType <ExtensibleModelBinderAttribute>().FirstOrDefault();

            if (attr == null)
            {
                provider = null;
                return(false);
            }

            if (typeof(ModelBinderProvider).IsAssignableFrom(attr.BinderType))
            {
                provider = (ModelBinderProvider)Activator.CreateInstance(attr.BinderType);
            }
            else if (typeof(IExtensibleModelBinder).IsAssignableFrom(attr.BinderType))
            {
                Type closedBinderType = (attr.BinderType.IsGenericTypeDefinition) ? attr.BinderType.MakeGenericType(modelType.GetGenericArguments()) : attr.BinderType;
                IExtensibleModelBinder binderInstance = (IExtensibleModelBinder)Activator.CreateInstance(closedBinderType);
                provider = new SimpleModelBinderProvider(modelType, binderInstance)
                {
                    SuppressPrefixCheck = attr.SuppressPrefixCheck
                };
            }
            else
            {
                string errorMessage = String.Format(CultureInfo.CurrentCulture, MvcResources.ModelBinderProviderCollection_InvalidBinderType,
                                                    attr.BinderType, typeof(ModelBinderProvider), typeof(IExtensibleModelBinder));
                throw new InvalidOperationException(errorMessage);
            }

            return(true);
        }
Exemplo n.º 2
0
        public void GetBinder_ModelMetadataReturnsReadOnly_ReturnsNull()
        {
            // Arrange
            ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
            {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(
                    null,
                    typeof(int[])
                    ),
                ModelName     = "foo",
                ValueProvider = new SimpleValueProvider {
                    { "foo[0]", "42" },
                }
            };

            bindingContext.ModelMetadata.IsReadOnly = true;

            ArrayModelBinderProvider binderProvider = new ArrayModelBinderProvider();

            // Act
            IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);

            // Assert
            Assert.Null(binder);
        }
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            CheckPropertyFilter(bindingContext);
            ExtensibleModelBindingContext newBindingContext = CreateNewBindingContext(bindingContext, bindingContext.ModelName);

            IExtensibleModelBinder binder = Providers.GetBinder(controllerContext, newBindingContext);

            if (binder == null && !String.IsNullOrEmpty(bindingContext.ModelName) &&
                bindingContext.FallbackToEmptyPrefix && bindingContext.ModelMetadata.IsComplexType)
            {
                // fallback to empty prefix?
                newBindingContext = CreateNewBindingContext(bindingContext, String.Empty /* modelName */);
                binder            = Providers.GetBinder(controllerContext, newBindingContext);
            }

            if (binder != null)
            {
                bool boundSuccessfully = binder.BindModel(controllerContext, newBindingContext);
                if (boundSuccessfully)
                {
                    // run validation and return the model
                    newBindingContext.ValidationNode.Validate(controllerContext, null /* parentNode */);
                    return(newBindingContext.Model);
                }
            }

            return(null); // something went wrong
        }
        public void GetBinder_FromAttribute_Provider_ReturnsBinder()
        {
            // Arrange
            ControllerContext             controllerContext = new ControllerContext();
            ExtensibleModelBindingContext bindingContext    = new ExtensibleModelBindingContext
            {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(
                    null,
                    typeof(ModelWithProviderAttribute_Provider)
                    )
            };

            ModelBinderProviderCollection providers = new ModelBinderProviderCollection();

            providers.RegisterBinderForType(
                typeof(ModelWithProviderAttribute_Provider),
                new Mock <IExtensibleModelBinder>().Object,
                true /* suppressPrefix */
                );

            // Act
            IExtensibleModelBinder binder = providers.GetBinder(controllerContext, bindingContext);

            // Assert
            Assert.IsType <CustomBinder>(binder);
        }
        public void GetBinderReturnsFirstBinderFromProviders()
        {
            // Arrange
            ControllerContext             controllerContext = new ControllerContext();
            ExtensibleModelBindingContext bindingContext    = new ExtensibleModelBindingContext
            {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(object))
            };
            IExtensibleModelBinder expectedBinder = new Mock <IExtensibleModelBinder>().Object;

            Mock <ModelBinderProvider> mockProvider = new Mock <ModelBinderProvider>();

            mockProvider.Setup(p => p.GetBinder(controllerContext, bindingContext)).Returns(expectedBinder);

            ModelBinderProviderCollection collection = new ModelBinderProviderCollection(new[]
            {
                new Mock <ModelBinderProvider>().Object,
                mockProvider.Object,
                new Mock <ModelBinderProvider>().Object
            });

            // Act
            IExtensibleModelBinder returned = collection.GetBinder(controllerContext, bindingContext);

            // Assert
            Assert.Equal(expectedBinder, returned);
        }
        public void GetBinderReturnsNullIfNoProviderMatches()
        {
            // Arrange
            ControllerContext             controllerContext = new ControllerContext();
            ExtensibleModelBindingContext bindingContext    = new ExtensibleModelBindingContext
            {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(
                    null,
                    typeof(object)
                    )
            };

            ModelBinderProviderCollection collection = new ModelBinderProviderCollection(
                new[] { new Mock <ModelBinderProvider>().Object, }
                );

            // Act
            IExtensibleModelBinder returned = collection.GetBinder(
                controllerContext,
                bindingContext
                );

            // Assert
            Assert.Null(returned);
        }
        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);
        }
        public void GetBinder_FromAttribute_Binder_ValueNotPresent_ReturnsNull()
        {
            // Arrange
            ControllerContext             controllerContext = new ControllerContext();
            ExtensibleModelBindingContext bindingContext    = new ExtensibleModelBindingContext
            {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(
                    null,
                    typeof(ModelWithProviderAttribute_Binder)
                    ),
                ModelName     = "foo",
                ValueProvider = new SimpleValueProvider {
                    { "bar", "barValue" }
                }
            };

            ModelBinderProviderCollection providers = new ModelBinderProviderCollection();

            providers.RegisterBinderForType(
                typeof(ModelWithProviderAttribute_Binder),
                new Mock <IExtensibleModelBinder>().Object,
                true /* suppressPrefix */
                );

            // Act
            IExtensibleModelBinder binder = providers.GetBinder(controllerContext, bindingContext);

            // Assert
            Assert.Null(binder);
        }
Exemplo n.º 9
0
        public void GetBinder_ModelTypeIsIncorrect_ReturnsNull()
        {
            // Arrange
            ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
            {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(
                    null,
                    typeof(List <int>)
                    ),
                ModelName     = "foo",
                ValueProvider = new SimpleValueProvider
                {
                    { "foo.key", 42 },
                    { "foo.value", "someValue" }
                }
            };

            KeyValuePairModelBinderProvider binderProvider = new KeyValuePairModelBinderProvider();

            // Act
            IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);

            // Assert
            Assert.Null(binder);
        }
        public void GetBinder_TypeMatches_Success_Factory_ReturnsBinder()
        {
            // Arrange
            IExtensibleModelBinder binderInstance = new Mock <IExtensibleModelBinder>().Object;

            Func <Type[], IExtensibleModelBinder> binderFactory = typeArguments =>
            {
                Assert.Equal(new[] { typeof(int) }, typeArguments);
                return(binderInstance);
            };

            GenericModelBinderProvider provider = new GenericModelBinderProvider(
                typeof(IList <>),
                binderFactory
                )
            {
                SuppressPrefixCheck = true
            };

            ExtensibleModelBindingContext bindingContext = GetBindingContext(typeof(List <int>));

            // Act
            IExtensibleModelBinder returnedBinder = provider.GetBinder(null, bindingContext);

            // Assert
            Assert.Same(binderInstance, returnedBinder);
        }
Exemplo n.º 11
0
        public void GetBinder_CorrectModelTypeAndValueProviderEntries_ReturnsBinder()
        {
            // Arrange
            ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
            {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(
                    null,
                    typeof(KeyValuePair <int, string>)
                    ),
                ModelName     = "foo",
                ValueProvider = new SimpleValueProvider
                {
                    { "foo.key", 42 },
                    { "foo.value", "someValue" }
                }
            };

            KeyValuePairModelBinderProvider binderProvider = new KeyValuePairModelBinderProvider();

            // Act
            IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);

            // Assert
            Assert.IsType <KeyValuePairModelBinder <int, string> >(binder);
        }
        public void BindModel_GoodValue_LinqBinary_Succeeds()
        {
            // Arrange
            ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
            {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(
                    null,
                    typeof(Binary)
                    ),
                ModelName     = "foo",
                ValueProvider = new SimpleValueProvider {
                    { "foo", _base64String }
                }
            };

            BinaryDataModelBinderProvider binderProvider = new BinaryDataModelBinderProvider();

            // Act
            IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
            bool retVal = binder.BindModel(null, bindingContext);

            // Assert
            Assert.True(retVal);
            Binary binaryModel = Assert.IsType <Binary>(bindingContext.Model);

            Assert.Equal(_base64Bytes, binaryModel.ToArray());
        }
        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 void GetBinder_TypeMatches_PrefixSuppressed_ReturnsFactoryInstance()
        {
            // Arrange
            int numExecutions = 0;
            IExtensibleModelBinder        theBinderInstance = new Mock <IExtensibleModelBinder>().Object;
            Func <IExtensibleModelBinder> factory           = delegate
            {
                numExecutions++;
                return(theBinderInstance);
            };

            SimpleModelBinderProvider provider = new SimpleModelBinderProvider(typeof(string), factory)
            {
                SuppressPrefixCheck = true
            };
            ExtensibleModelBindingContext bindingContext = GetBindingContext(typeof(string));

            // Act
            IExtensibleModelBinder returnedBinder = provider.GetBinder(null, bindingContext);

            returnedBinder = provider.GetBinder(null, bindingContext);

            // Assert
            Assert.Equal(2, numExecutions);
            Assert.Equal(theBinderInstance, returnedBinder);
        }
        public void GetPossibleBinderInstance_Match_ReturnsBinder()
        {
            // Act
            IExtensibleModelBinder binder = ModelBinderUtil.GetPossibleBinderInstance(typeof(List <int>), typeof(List <>), typeof(SampleGenericBinder <>));

            // Assert
            Assert.IsType <SampleGenericBinder <int> >(binder);
        }
 public void RegisterBinderForType(Type modelType, IExtensibleModelBinder modelBinder)
 {
     RegisterBinderForType(
         modelType,
         modelBinder,
         false /* suppressPrefixCheck */
         );
 }
        public void GetPossibleBinderInstance_NoMatch_ReturnsNull()
        {
            // Act
            IExtensibleModelBinder binder = ModelBinderUtil.GetPossibleBinderInstance(typeof(ArraySegment <int>), typeof(List <>), typeof(SampleGenericBinder <>));

            // Assert
            Assert.Null(binder);
        }
        internal void RegisterBinderForType(Type modelType, IExtensibleModelBinder modelBinder, bool suppressPrefixCheck)
        {
            SimpleModelBinderProvider provider = new SimpleModelBinderProvider(modelType, modelBinder)
            {
                SuppressPrefixCheck = suppressPrefixCheck
            };

            InsertSimpleProviderAtFront(provider);
        }
Exemplo n.º 19
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);
        }
        internal IExtensibleModelBinder GetRequiredBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
        {
            IExtensibleModelBinder binder = GetBinder(controllerContext, bindingContext);

            if (binder == null)
            {
                throw Error.ModelBinderProviderCollection_BinderForTypeNotFound(bindingContext.ModelType);
            }
            return(binder);
        }
        public SimpleModelBinderProvider(Type modelType, IExtensibleModelBinder modelBinder) {
            if (modelType == null) {
                throw new ArgumentNullException("modelType");
            }
            if (modelBinder == null) {
                throw new ArgumentNullException("modelBinder");
            }

            _modelType = modelType;
            _modelBinderFactory = () => modelBinder;
        }
        public void GetBinder_TypeMatches_ReturnsBinder()
        {
            // Arrange
            ComplexModelDtoModelBinderProvider provider       = new ComplexModelDtoModelBinderProvider();
            ExtensibleModelBindingContext      bindingContext = GetBindingContext(typeof(ComplexModelDto));

            // Act
            IExtensibleModelBinder binder = provider.GetBinder(null, bindingContext);

            // Assert
            Assert.IsType <ComplexModelDtoModelBinder>(binder);
        }
        public void GetBinder_TypeDoesNotMatch_ReturnsNull()
        {
            // Arrange
            ComplexModelDtoModelBinderProvider provider       = new ComplexModelDtoModelBinderProvider();
            ExtensibleModelBindingContext      bindingContext = GetBindingContext(typeof(object));

            // Act
            IExtensibleModelBinder binder = provider.GetBinder(null, bindingContext);

            // Assert
            Assert.Null(binder);
        }
Exemplo n.º 24
0
        public void GetBinder_TypeConverterExistsFromString_ReturnsNull()
        {
            // Arrange
            ExtensibleModelBindingContext bindingContext = GetBindingContext(typeof(int)); // TypeConverter exists Int32 -> String

            TypeConverterModelBinderProvider provider = new TypeConverterModelBinderProvider();

            // Act
            IExtensibleModelBinder binder = provider.GetBinder(null, bindingContext);

            // Assert
            Assert.IsType <TypeConverterModelBinder>(binder);
        }
        public GenericModelBinderProvider(Type modelType, IExtensibleModelBinder modelBinder) {
            if (modelType == null) {
                throw new ArgumentNullException("modelType");
            }
            if (modelBinder == null) {
                throw new ArgumentNullException("modelBinder");
            }

            ValidateParameters(modelType, null /* modelBinderType */);

            _modelType = modelType;
            _modelBinderFactory = _ => modelBinder;
        }
Exemplo n.º 26
0
        public void GetBinder_NoTypeConverterExistsFromString_ReturnsNull()
        {
            // Arrange
            ExtensibleModelBindingContext bindingContext = GetBindingContext(typeof(void)); // no TypeConverter exists Void -> String

            TypeConverterModelBinderProvider provider = new TypeConverterModelBinderProvider();

            // Act
            IExtensibleModelBinder binder = provider.GetBinder(null, bindingContext);

            // Assert
            Assert.Null(binder);
        }
Exemplo n.º 27
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 SimpleModelBinderProvider(Type modelType, IExtensibleModelBinder modelBinder)
        {
            if (modelType == null)
            {
                throw new ArgumentNullException("modelType");
            }
            if (modelBinder == null)
            {
                throw new ArgumentNullException("modelBinder");
            }

            _modelType          = modelType;
            _modelBinderFactory = () => modelBinder;
        }
        public void GetBinder_TypeDoesNotMatch_ReturnsNull()
        {
            // Arrange
            SimpleModelBinderProvider provider = new SimpleModelBinderProvider(typeof(string), new Mock <IExtensibleModelBinder>().Object)
            {
                SuppressPrefixCheck = true
            };
            ExtensibleModelBindingContext bindingContext = GetBindingContext(typeof(object));

            // Act
            IExtensibleModelBinder binder = provider.GetBinder(null, bindingContext);

            // Assert
            Assert.Null(binder);
        }
        public void GetBinder_TypeDoesNotMatch_ModelTypeIsNotInterface_ReturnsNull()
        {
            // Arrange
            GenericModelBinderProvider provider = new GenericModelBinderProvider(typeof(List <>), typeof(CollectionModelBinder <>))
            {
                SuppressPrefixCheck = true
            };
            ExtensibleModelBindingContext bindingContext = GetBindingContext(typeof(object));

            // Act
            IExtensibleModelBinder binder = provider.GetBinder(null, bindingContext);

            // Assert
            Assert.Null(binder);
        }
Exemplo n.º 31
0
        public void GetBinder_NullValueProviderResult_ReturnsNull()
        {
            // Arrange
            ExtensibleModelBindingContext bindingContext = GetBindingContext(typeof(int));

            bindingContext.ValueProvider = new SimpleValueProvider(); // clear the ValueProvider

            TypeConverterModelBinderProvider provider = new TypeConverterModelBinderProvider();

            // Act
            IExtensibleModelBinder binder = provider.GetBinder(null, bindingContext);

            // Assert
            Assert.Null(binder);
        }
        public GenericModelBinderProvider(Type modelType, IExtensibleModelBinder modelBinder)
        {
            if (modelType == null)
            {
                throw new ArgumentNullException("modelType");
            }
            if (modelBinder == null)
            {
                throw new ArgumentNullException("modelBinder");
            }

            ValidateParameters(modelType, null /* modelBinderType */);

            _modelType          = modelType;
            _modelBinderFactory = _ => modelBinder;
        }