public async Task BindModel_ComplexCollection_Succeeds(bool isReadOnly)
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider
            {
                { "someName.index", new[] { "foo", "bar", "baz" } },
                { "someName[foo]", "42" },
                { "someName[bar]", "100" },
                { "someName[baz]", "200" }
            };
            var bindingContext = GetModelBindingContext(valueProvider, isReadOnly);
            var modelState = bindingContext.ModelState;
            var binder = new CollectionModelBinder<int>();

            // Act
            var result = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.NotNull(result);
            Assert.True(result.IsModelSet);

            var list = Assert.IsAssignableFrom<IList<int>>(result.Model);
            Assert.Equal(new[] { 42, 100, 200 }, list.ToArray());

            Assert.True(modelState.IsValid);
        }
        public async Task BindModelSetsModelToNullOnNullOrEmptyString(string value)
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider()
            {
                { "foo", value }
            };

            var bindingContext = GetBindingContext(valueProvider, typeof(byte[]));
            var binder = new ByteArrayModelBinder();

            // Act
            var binderResult = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.NotNull(binderResult);
            Assert.False(binderResult.IsModelSet);
            Assert.Equal("foo", binderResult.Key);
            Assert.Null(binderResult.Model);

            var modelState = Assert.Single(bindingContext.ModelState);
            Assert.Equal("foo", modelState.Key);
            Assert.NotNull(modelState.Value.Value);
            Assert.Equal(value, modelState.Value.Value.RawValue);
        }
Example #3
0
        public async Task BindModel_MissingValue_ReturnsTrue()
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider();
            var bindingContext = GetBindingContext(valueProvider);
            var binder = new KeyValuePairModelBinder<int, string>();

            // Act
            bool retVal = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.True(retVal);
            Assert.Null(bindingContext.Model);
            Assert.Equal(new[] { "someName.key" }, bindingContext.ValidationNode.ChildNodes.Select(n => n.ModelStateKey).ToArray());
        }
Example #4
0
        public async Task BindModel_MissingKey_ReturnsFalse()
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider();
            var bindingContext = GetBindingContext(valueProvider, Mock.Of<IModelBinder>());
            var binder = new KeyValuePairModelBinder<int, string>();

            // Act
            bool retVal = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.False(retVal);
            Assert.Null(bindingContext.Model);
            Assert.Empty(bindingContext.ValidationNode.ChildNodes);
        }
        public async Task GetBinder_ModelMetadataReturnsReadOnly_ReturnsNull()
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider
            {
                { "foo[0]", "42" },
            };
            var bindingContext = GetBindingContext(valueProvider, isReadOnly: true);
            var binder = new ArrayModelBinder<int>();

            // Act
            var bound = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.Null(bound);
        }
        public async Task BindModelSetsModelToNullOnNullOrEmptyString(string value)
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider()
            {
                { "foo", value }
            };

            var bindingContext = GetBindingContext(valueProvider, typeof(byte[]));
            var binder = new ByteArrayModelBinder();

            // Act
            var binderResult = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.Null(binderResult);
        }
        public async Task BindComplexCollectionFromIndexes_FiniteIndexes()
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider
            {
                { "someName[foo]", "42" },
                { "someName[baz]", "200" }
            };
            var bindingContext = GetModelBindingContext(valueProvider);
            var binder = new CollectionModelBinder<int>();

            // Act
            var boundCollection = await binder.BindComplexCollectionFromIndexes(bindingContext, new[] { "foo", "bar", "baz" });

            // Assert
            Assert.Equal(new[] { 42, 0, 200 }, boundCollection.ToArray());
        }
        public async Task BindComplexCollectionFromIndexes_InfiniteIndexes()
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider
            {
                { "someName[0]", "42" },
                { "someName[1]", "100" },
                { "someName[3]", "400" }
            };
            var bindingContext = GetModelBindingContext(valueProvider);
            var binder = new CollectionModelBinder<int>();

            // Act
            var boundCollection = await binder.BindComplexCollectionFromIndexes(bindingContext, indexNames: null);

            // Assert
            Assert.Equal(new[] { 42, 100 }, boundCollection.ToArray());
        }
        public async Task BindModel()
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider()
            {
                { "foo", "Fys1" }
            };

            var bindingContext = GetBindingContext(valueProvider, typeof(byte[]));
            var binder = new ByteArrayModelBinder();

            // Act
            var binderResult = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.NotNull(binderResult);
            var bytes = Assert.IsType<byte[]>(binderResult.Model);
            Assert.Equal(new byte[] { 23, 43, 53 }, bytes);
        }
Example #10
0
        public async Task BindModel_ComplexCollection()
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider
            {
                { "someName.index", new[] { "foo", "bar", "baz" } },
                { "someName[foo]", "42" },
                { "someName[bar]", "100" },
                { "someName[baz]", "200" }
            };
            var bindingContext = GetModelBindingContext(valueProvider);
            var binder = new CollectionModelBinder<int>();

            // Act
            bool retVal = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.Equal(new[] { 42, 100, 200 }, ((List<int>)bindingContext.Model).ToArray());
        }
        public async Task BindModel_MissingValue_ReturnsResult_AndAddsModelValidationError()
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider();

            // Create int binder to create the value but not the key.
            var bindingContext = GetBindingContext(valueProvider, CreateIntBinder());
            var binder = new KeyValuePairModelBinder<int, string>();

            // Act
            var result = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.NotNull(result);
            Assert.Null(result.Model);
            Assert.False(bindingContext.ModelState.IsValid);
            Assert.Equal("someName", bindingContext.ModelName);
            Assert.Equal(bindingContext.ModelState["someName.Value"].Errors.First().ErrorMessage, "A value is required.");
        }
Example #12
0
        public async Task BindModel()
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider
            {
                { "someName[0]", "42" },
                { "someName[1]", "84" }
            };
            ModelBindingContext bindingContext = GetBindingContext(valueProvider);
            var binder = new ArrayModelBinder<int>();

            // Act
            var retVal = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.True(retVal);

            int[] array = bindingContext.Model as int[];
            Assert.Equal(new[] { 42, 84 }, array);
        }
Example #13
0
        public async Task BindModel_SubBindingSucceeds()
        {
            // Arrange
            var binderProviders = new Mock<IModelBinderProvider>();
            binderProviders.SetupGet(b => b.ModelBinders)
                           .Returns(new[] { CreateStringBinder(), CreateIntBinder() });
            var innerBinder = new CompositeModelBinder(binderProviders.Object);
            var valueProvider = new SimpleHttpValueProvider();
            var bindingContext = GetBindingContext(valueProvider, innerBinder);
            
            var binder = new KeyValuePairModelBinder<int, string>();

            // Act
            var retVal = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.True(retVal);
            Assert.Equal(new KeyValuePair<int, string>(42, "some-value"), bindingContext.Model);
            Assert.Equal(new[] { "someName.key", "someName.value" }, bindingContext.ValidationNode.ChildNodes.Select(n => n.ModelStateKey).ToArray());
        }
Example #14
0
        public void ModelBinderTest()
        {
            var uploadForms = new SimpleHttpValueProvider();
            uploadForms["Amount"] = "123";
            uploadForms["fkSourceID"] = "1";
            uploadForms["fkDestinationID"] = "3";
            uploadForms["fkActorID"] = "3";
            uploadForms["Date"] = "2015-01-06T07:33:29.139Z";
            uploadForms["SourceURL"] = "xvideos.com";

            Mock<IModelBinder> mockIntBinder = new Mock<IModelBinder>();
            HttpActionContext actionContext = ContextUtils.CreateActionContext();
            ModelBindingContext bindingContext = new ModelBindingContext
            {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(Transaction)),
                ValueProvider = uploadForms
            };

            bool retVal = actionContext.Bind(bindingContext);
            Console.WriteLine(retVal);
        }
Example #15
0
        public async Task BindModelAddsModelErrorsOnInvalidCharacters()
        {
            // Arrange
            var expected = "The value '\"Fys1\"' is not valid for foo.";

            var valueProvider = new SimpleHttpValueProvider()
            {
                { "foo", "\"Fys1\"" }
            };

            var bindingContext = GetBindingContext(valueProvider, typeof(byte[]));
            var binder = new ByteArrayModelBinder();

            // Act
            var binderResult = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.NotNull(binderResult);
            Assert.False(bindingContext.ModelState.IsValid);
            var error = Assert.Single(bindingContext.ModelState["foo"].Errors);
            Assert.Equal(expected, error.ErrorMessage);
        }
Example #16
0
        public async Task BindModelAsync_ValueProviderContainPrefix_Succeeds()
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider
            {
                { "someName[0]", "42" },
                { "someName[1]", "84" },
            };
            var bindingContext = GetBindingContext(valueProvider);
            var modelState = bindingContext.ModelState;
            var binder = new ArrayModelBinder<int>();

            // Act
            var result = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.NotNull(result);

            var array = Assert.IsType<int[]>(result.Model);
            Assert.Equal(new[] { 42, 84 }, array);
            Assert.True(modelState.IsValid);
        }
        public async Task BindModel_MissingKeyAndMissingValue_DoNotAddModelStateError()
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider();

            // Create int binder to create the value but not the key.
            var bindingContext = GetBindingContext(valueProvider);
            var mockBinder = new Mock<IModelBinder>();
            mockBinder.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
                      .Returns(Task.FromResult<ModelBindingResult>(null));

            bindingContext.OperationBindingContext.ModelBinder = mockBinder.Object;
            var binder = new KeyValuePairModelBinder<int, string>();

            // Act
            var result = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.Null(result);
            Assert.True(bindingContext.ModelState.IsValid);
            Assert.Equal(0, bindingContext.ModelState.ErrorCount);
        }
        public async Task BindModel_WithDefaultBinders_BindsComplexType()
        {
            // Arrange
            var binder = CreateBinderWithDefaults();

            var valueProvider = new SimpleHttpValueProvider
            {
                { "firstName", "firstName-value"},
                { "lastName", "lastName-value"},
                { "friends[0].firstName", "first-friend"},
                { "friends[0].age", "40"},
                { "friends[0].friends[0].firstname", "nested friend"},
                { "friends[1].firstName", "some other"},
                { "friends[1].lastName", "name"},
                { "resume", "4+mFeTp3tPF=" }
            };

            var bindingContext = CreateBindingContext(binder, valueProvider, typeof(Person));

            // Act
            var result = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.NotNull(result);
            var model = Assert.IsType<Person>(result.Model);
            Assert.Equal("firstName-value", model.FirstName);
            Assert.Equal("lastName-value", model.LastName);
            Assert.Equal(2, model.Friends.Count);
            Assert.Equal("first-friend", model.Friends[0].FirstName);
            Assert.Equal(40, model.Friends[0].Age);
            var nestedFriend = Assert.Single(model.Friends[0].Friends);
            Assert.Equal("nested friend", nestedFriend.FirstName);
            Assert.Equal("some other", model.Friends[1].FirstName);
            Assert.Equal("name", model.Friends[1].LastName);
            Assert.Equal(new byte[] { 227, 233, 133, 121, 58, 119, 180, 241 }, model.Resume);
        }
Example #19
0
        public async Task BindModel_ReturnsWithIsModelSetFalse_WhenValueNotFound()
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider()
            {
                { "someName", "" }
            };

            var bindingContext = GetBindingContext(valueProvider, typeof(byte[]));
            var binder = new ByteArrayModelBinder();

            // Act
            var binderResult = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.NotNull(binderResult);
            Assert.False(binderResult.IsModelSet);
            Assert.Equal("foo", binderResult.Key);
            Assert.Null(binderResult.Model);

            Assert.Empty(bindingContext.ModelState); // No submitted data for "foo".
        }
Example #20
0
        public async Task BindModel_WithDefaultValidators_ValidatesInstance()
        {
            // Arrange
            var validatorProvider = new DataAnnotationsModelValidatorProvider();
            var binder = CreateBinderWithDefaults();
            var valueProvider = new SimpleHttpValueProvider
            {
                { "user.password", "password" },
                { "user.confirmpassword", "password" },
            };
            var bindingContext = CreateBindingContext(binder, valueProvider, typeof(User), new[] { validatorProvider });
            bindingContext.ModelName = "user";

            // Act
            var isBound = await binder.BindModelAsync(bindingContext);

            // Assert
            var error = Assert.Single(bindingContext.ModelState["user"].Errors);
            Assert.Equal("Password does not meet complexity requirements.", error.ErrorMessage);
        }
        public async Task BindModel_WithDefaultBinders_BindsSimpleType()
        {
            // Arrange
            var binder = CreateBinderWithDefaults();

            var valueProvider = new SimpleHttpValueProvider
            {
                { "firstName", "firstName-value"},
                { "lastName", "lastName-value"}
            };
            var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel));

            // Act
            var result = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.NotNull(result);
            var model = Assert.IsType<SimplePropertiesModel>(result.Model);
            Assert.Equal("firstName-value", model.FirstName);
            Assert.Equal("lastName-value", model.LastName);

            Assert.NotNull(result.ValidationNode);
            Assert.Equal(2, result.ValidationNode.ChildNodes.Count);
            Assert.Equal("", result.ValidationNode.Key);
            Assert.Equal(bindingContext.ModelMetadata, result.ValidationNode.ModelMetadata);
            model = Assert.IsType<SimplePropertiesModel>(result.ValidationNode.Model);
            Assert.Equal("firstName-value", model.FirstName);
            Assert.Equal("lastName-value", model.LastName);

            Assert.Equal(2, result.ValidationNode.ChildNodes.Count);

            var validationNode = result.ValidationNode.ChildNodes[0];
            Assert.Equal("FirstName", validationNode.Key);
            Assert.Equal("firstName-value", validationNode.Model);
            Assert.Empty(validationNode.ChildNodes);

            validationNode = result.ValidationNode.ChildNodes[1];
            Assert.Equal("LastName", validationNode.Key);
            Assert.Equal("lastName-value", validationNode.Model);
            Assert.Empty(validationNode.ChildNodes);
        }
Example #22
0
        public async Task BindModelAsync_ModelMetadataNotReadOnly_ModelNonNull_FailsSilently(int[] model)
        {
            // Arrange
            var arrayLength = model.Length;
            var valueProvider = new SimpleHttpValueProvider
            {
                { "someName[0]", "42" },
                { "someName[1]", "84" },
            };

            var bindingContext = GetBindingContext(valueProvider, isReadOnly: false);
            var modelState = bindingContext.ModelState;
            bindingContext.Model = model;
            var binder = new ArrayModelBinder<int>();

            // Act
            var result = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.NotNull(result);
            Assert.True(result.IsModelSet);
            Assert.Same(model, result.Model);

            Assert.True(modelState.IsValid);
            for (var i = 0; i < arrayLength; i++)
            {
                // Array should be unchanged.
                Assert.Equal(357, model[i]);
            }
        }
Example #23
0
        public async Task BindModelAsync_ModelMetadataReadOnly_ReturnsNull(int[] model)
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider
            {
                { "someName[0]", "42" },
                { "someName[1]", "84" },
            };
            var bindingContext = GetBindingContext(valueProvider, isReadOnly: true);
            bindingContext.Model = model;
            var binder = new ArrayModelBinder<int>();

            // Act
            var result = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.Null(result);
        }
        public async Task BindModel_SubBindingSucceeds()
        {
            // Arrange
            var innerBinder = new CompositeModelBinder(new[] { CreateStringBinder(), CreateIntBinder() });
            var valueProvider = new SimpleHttpValueProvider();
            var bindingContext = GetBindingContext(valueProvider, innerBinder);

            var binder = new KeyValuePairModelBinder<int, string>();

            // Act
            var result = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.NotNull(result);
            Assert.Equal(new KeyValuePair<int, string>(42, "some-value"), result.Model);
            Assert.NotNull(result.ValidationNode);
            Assert.Equal(new KeyValuePair<int, string>(42, "some-value"), result.ValidationNode.Model);
            Assert.Equal("someName", result.ValidationNode.Key);

            var validationNode = result.ValidationNode.ChildNodes[0];
            Assert.Equal("someName.Key", validationNode.Key);
            Assert.Equal(42, validationNode.Model);
            Assert.Empty(validationNode.ChildNodes);

            validationNode = result.ValidationNode.ChildNodes[1];
            Assert.Equal("someName.Value", validationNode.Key);
            Assert.Equal("some-value", validationNode.Model);
            Assert.Empty(validationNode.ChildNodes);
        }
        public async Task BindModel_DoesNotAddAValidationNode_IfModelIsNotSet()
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider();
            var mockBinder = new Mock<IModelBinder>();
            mockBinder
                .Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
                .Returns(
                    delegate (ModelBindingContext context)
                    {
                        return Task.FromResult(
                            new ModelBindingResult(model: 42, key: "someName", isModelSet: false));
                    });
            var binder = CreateCompositeBinder(mockBinder.Object);
            var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel));

            // Act
            var result = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.Null(result);
        }
        private static ModelBindingContext GetModelBindingContext(bool isReadOnly)
        {
            var metadataProvider = new TestModelMetadataProvider();
            metadataProvider.ForType<List<int>>().BindingDetails(bd => bd.IsReadOnly = isReadOnly);
            var valueProvider = new SimpleHttpValueProvider
            {
                { "someName[0]", new KeyValuePair<int, string>(42, "forty-two") },
                { "someName[1]", new KeyValuePair<int, string>(84, "eighty-four") },
            };

            var bindingContext = new ModelBindingContext
            {
                ModelMetadata = metadataProvider.GetMetadataForType(typeof(IDictionary<int, string>)),
                ModelName = "someName",
                ValueProvider = valueProvider,
                OperationBindingContext = new OperationBindingContext
                {
                    ModelBinder = CreateKvpBinder(),
                    MetadataProvider = metadataProvider
                }
            };

            return bindingContext;
        }
        public async Task BindModel_DoesNotAddAValidationNode_IfModelBindingResultIsNull()
        {
            // Arrange
            var mockBinder = new Mock<IModelBinder>();
            mockBinder
                .Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
                .Returns(Task.FromResult<ModelBindingResult>(null));
            var binder = CreateCompositeBinder(mockBinder.Object);
            var valueProvider = new SimpleHttpValueProvider();
            var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel));

            // Act
            var result = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.Null(result);
        }
        public async Task BindModel_SimpleCollection_BindingContextModelNonNull_Succeeds(bool isReadOnly)
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider
            {
                { "someName", new[] { "42", "100", "200" } }
            };
            var bindingContext = GetModelBindingContext(valueProvider, isReadOnly);
            var modelState = bindingContext.ModelState;
            var list = new List<int>();
            bindingContext.Model = list;
            var binder = new CollectionModelBinder<int>();

            // Act
            var result = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.NotNull(result);
            Assert.True(result.IsModelSet);

            Assert.Same(list, result.Model);
            Assert.Equal(new[] { 42, 100, 200 }, list.ToArray());

            Assert.True(modelState.IsValid);
        }
        public async Task BindModel_UsesTheValidationNodeOnModelBindingResult_IfPresent()
        {
            // Arrange
            var valueProvider = new SimpleHttpValueProvider();
            ModelValidationNode validationNode = null;

            var mockBinder = new Mock<IModelBinder>();
            mockBinder
                .Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
                .Returns(
                    delegate (ModelBindingContext context)
                    {
                        validationNode = new ModelValidationNode("someName", context.ModelMetadata, 42);
                        return Task.FromResult(
                            new ModelBindingResult(42, "someName", isModelSet: true, validationNode: validationNode));
                    });
            var binder = CreateCompositeBinder(mockBinder.Object);
            var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel));

            // Act
            var result = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.NotNull(result);
            Assert.True(result.IsModelSet);
            Assert.Same(validationNode, result.ValidationNode);
        }
        public async Task BindModel_WithDefaultBinders_BindsSimpleType()
        {
            // Arrange
            var binder = CreateBinderWithDefaults();

            var valueProvider = new SimpleHttpValueProvider
            {
                { "firstName", "firstName-value"},
                { "lastName", "lastName-value"}
            };
            var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel));

            // Act
            var result = await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.NotNull(result);
            var model = Assert.IsType<SimplePropertiesModel>(result.Model);
            Assert.Equal("firstName-value", model.FirstName);
            Assert.Equal("lastName-value", model.LastName);
        }