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); }
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); }
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); }
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); }
// 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); }
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; }
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); }
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 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); }
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); }