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); }
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()); }
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); }
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."); }
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); }
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()); }
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); }
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); }
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); }
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". }
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); }
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]); } }
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); }