public async Task BindActionArgumentsAsync_DoesNotSetNullValues_ForNonNullableProperties(bool isModelSet) { // Arrange var actionDescriptor = GetActionDescriptor(); actionDescriptor.BoundProperties.Add( new ParameterDescriptor { Name = nameof(TestController.NonNullableProperty), BindingInfo = new BindingInfo() { BindingSource = BindingSource.Custom }, ParameterType = typeof(int) }); var controllerContext = GetControllerContext(actionDescriptor); var controller = new TestController(); var arguments = new Dictionary <string, object>(StringComparer.Ordinal); var binder = new StubModelBinder(ModelBindingResult.Success(model: null)); var factory = GetModelBinderFactory(binder); var argumentBinder = GetArgumentBinder(factory); // Some non default value. controller.NonNullableProperty = -1; // Act await argumentBinder.BindArgumentsAsync(controllerContext, controller, arguments); // Assert Assert.Equal(-1, controller.NonNullableProperty); }
public async Task BindActionArgumentsAsync_SetsNullValues_ForNullableProperties() { // Arrange var actionDescriptor = GetActionDescriptor(); actionDescriptor.BoundProperties.Add( new ParameterDescriptor { Name = "NullableProperty", BindingInfo = new BindingInfo() { BindingSource = BindingSource.Custom }, ParameterType = typeof(int?) }); var controllerContext = GetControllerContext(actionDescriptor); var binder = new StubModelBinder(ModelBindingResult.Success(key: string.Empty, model: null)); var factory = GetModelBinderFactory(binder); var argumentBinder = GetArgumentBinder(factory); var controller = new TestController(); // Some non default value. controller.NullableProperty = -1; // Act var result = await argumentBinder.BindActionArgumentsAsync(controllerContext, controller); // Assert Assert.Null(controller.NullableProperty); }
public async Task TryBindStrongModel_InnerBinderReturnsAResult_ReturnsInnerBinderResult( object model, bool isSuccess) { // Arrange ModelBindingResult innerResult; if (isSuccess) { innerResult = ModelBindingResult.Success(model); } else { innerResult = ModelBindingResult.Failed(); } var innerBinder = new StubModelBinder(context => { Assert.Equal("someName.Key", context.ModelName); return(innerResult); }); var valueProvider = new SimpleValueProvider(); var bindingContext = GetBindingContext(valueProvider, typeof(KeyValuePair <int, string>)); var binder = new KeyValuePairModelBinder <int, string>(innerBinder, innerBinder, NullLoggerFactory.Instance); // Act var result = await binder.TryBindStrongModel <int>(bindingContext, innerBinder, "Key", "someName.Key"); // Assert Assert.Equal(innerResult, result); Assert.Empty(bindingContext.ModelState); }
public async Task BindActionArgumentsAsync_DoesNotSetNullValues_ForNonNullableProperties(bool isModelSet) { // Arrange var actionDescriptor = GetActionDescriptor(); actionDescriptor.BoundProperties.Add( new ParameterDescriptor { Name = nameof(TestController.NonNullableProperty), BindingInfo = new BindingInfo() { BindingSource = BindingSource.Custom }, ParameterType = typeof(int) }); var binder = new StubModelBinder(ModelBindingResult.Success(string.Empty, model: null)); var controllerContext = GetControllerContext(actionDescriptor); controllerContext.ModelBinders.Add(binder); controllerContext.ValueProviders.Add(new SimpleValueProvider()); var argumentBinder = GetArgumentBinder(); var controller = new TestController(); // Some non default value. controller.NonNullableProperty = -1; // Act var result = await argumentBinder.BindActionArgumentsAsync(controllerContext, controller); // Assert Assert.Equal(-1, controller.NonNullableProperty); }
public async Task BindActionArgumentsAsync_SupportsRequestPredicate_ForPropertiesAndParameters_Bound() { // Arrange var actionDescriptor = GetActionDescriptor(); actionDescriptor.Parameters.Add(new ParameterDescriptor { Name = "test-parameter", BindingInfo = new BindingInfo() { BindingSource = BindingSource.Custom, // Simulates [BindProperty] on a parameter RequestPredicate = ((IRequestPredicateProvider) new BindPropertyAttribute()).RequestPredicate, }, ParameterType = typeof(string) }); actionDescriptor.BoundProperties.Add(new ParameterDescriptor { Name = nameof(TestController.NullableProperty), BindingInfo = new BindingInfo() { BindingSource = BindingSource.Custom, // Simulates [BindProperty] on a property RequestPredicate = ((IRequestPredicateProvider) new BindPropertyAttribute()).RequestPredicate, }, ParameterType = typeof(string) }); var controllerContext = GetControllerContext(actionDescriptor); controllerContext.HttpContext.Request.Method = "POST"; var controller = new TestController(); var arguments = new Dictionary <string, object>(StringComparer.Ordinal); var binder = new StubModelBinder(ModelBindingResult.Success(model: null)); var factory = GetModelBinderFactory(binder); var parameterBinder = GetParameterBinder(factory); // Some non default value. controller.NullableProperty = -1; // Act var binderDelegate = ControllerBinderDelegateProvider.CreateBinderDelegate( parameterBinder, factory, TestModelMetadataProvider.CreateDefaultProvider(), actionDescriptor); await binderDelegate(controllerContext, controller, arguments); // Assert Assert.Null(controller.NullableProperty); Assert.Contains("test-parameter", arguments.Keys); Assert.Null(arguments["test-parameter"]); }
private static IModelBinder CreateIntBinder(bool success = true) { var mockIntBinder = new StubModelBinder(mbc => { if (mbc.ModelType == typeof(int) && success) { var model = 42; return(ModelBindingResult.Success(model)); } return(ModelBindingResult.Failed()); }); return(mockIntBinder); }
public async Task BindActionArgumentsAsync_SetsNullValues_ForNullableProperties() { // Arrange var actionDescriptor = GetActionDescriptor(); actionDescriptor.BoundProperties.Add( new ParameterDescriptor { Name = "NullableProperty", BindingInfo = new BindingInfo() { BindingSource = BindingSource.Custom }, ParameterType = typeof(int?) }); var controllerContext = GetControllerContext(actionDescriptor); var controller = new TestController(); var arguments = new Dictionary <string, object>(StringComparer.Ordinal); var binder = new StubModelBinder(ModelBindingResult.Success(model: null)); var factory = GetModelBinderFactory(binder); var parameterBinder = GetParameterBinder(factory); // Some non default value. controller.NullableProperty = -1; // Act var binderDelegate = ControllerBinderDelegateProvider.CreateBinderDelegate( parameterBinder, factory, TestModelMetadataProvider.CreateDefaultProvider(), actionDescriptor); await binderDelegate(controllerContext, controller, arguments); // Assert Assert.Null(controller.NullableProperty); }
public async Task BindSimpleCollection_SubBindingSucceeds() { // Arrange var culture = new CultureInfo("fr-FR"); var bindingContext = GetModelBindingContext(new SimpleValueProvider()); var elementBinder = new StubModelBinder(mbc => { Assert.Equal("someName", mbc.ModelName); mbc.Result = ModelBindingResult.Success(42); }); var modelBinder = new CollectionModelBinder <int>(elementBinder, NullLoggerFactory.Instance); // Act var boundCollection = await modelBinder.BindSimpleCollection( bindingContext, new ValueProviderResult(new string[] { "0" })); // Assert Assert.Equal(new[] { 42 }, boundCollection.Model.ToArray()); }
public async Task BindActionArgumentsAsync_SetsMultipleControllerProperties() { // Arrange var boundPropertyTypes = new Dictionary <string, Type> { { nameof(TestController.ArrayProperty), typeof(string[]) }, // Skipped { nameof(TestController.CollectionProperty), typeof(List <string>) }, { nameof(TestController.NonCollectionProperty), typeof(Person) }, // Skipped { nameof(TestController.NullCollectionProperty), typeof(List <string>) }, // Skipped { nameof(TestController.StringProperty), typeof(string) }, }; var inputPropertyValues = new Dictionary <string, object> { { nameof(TestController.ArrayProperty), new string[] { "hello", "world" } }, { nameof(TestController.CollectionProperty), new List <string> { "hello", "world" } }, { nameof(TestController.NonCollectionProperty), new Person { Name = "Fred" } }, { nameof(TestController.NullCollectionProperty), new List <string> { "hello", "world" } }, { nameof(TestController.StringProperty), "Hello" }, }; var expectedPropertyValues = new Dictionary <string, object> { { nameof(TestController.ArrayProperty), new string[] { "goodbye" } }, { nameof(TestController.CollectionProperty), new List <string> { "hello", "world" } }, { nameof(TestController.NonCollectionProperty), new Person { Name = "Ginger" } }, { nameof(TestController.NullCollectionProperty), null }, { nameof(TestController.StringProperty), "Hello" }, }; var actionDescriptor = GetActionDescriptor(); foreach (var keyValuePair in boundPropertyTypes) { actionDescriptor.BoundProperties.Add( new ParameterDescriptor { Name = keyValuePair.Key, BindingInfo = new BindingInfo(), ParameterType = keyValuePair.Value, }); } var controllerContext = GetControllerContext(actionDescriptor); var binder = new StubModelBinder(bindingContext => { // BindingContext.ModelName will be string.Empty here. This is a 'fallback to empty prefix' // because the value providers have no data. object model; if (inputPropertyValues.TryGetValue(bindingContext.FieldName, out model)) { bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model); } else { bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName); } }); var factory = GetModelBinderFactory(binder); controllerContext.ValueProviders.Add(new SimpleValueProvider()); var argumentBinder = GetArgumentBinder(factory); var controller = new TestController(); // Act var result = await argumentBinder.BindActionArgumentsAsync(controllerContext, controller); // Assert Assert.Equal(new string[] { "goodbye" }, controller.ArrayProperty); // Skipped Assert.Equal(new List <string> { "hello", "world" }, controller.CollectionProperty); Assert.Equal(new Person { Name = "Ginger" }, controller.NonCollectionProperty); // Skipped Assert.Null(controller.NullCollectionProperty); // Skipped Assert.Null(controller.UntouchedProperty); // Not bound Assert.Equal("Hello", controller.StringProperty); }
private static IModelBinder CreateIntBinder(bool success = true) { var mockIntBinder = new StubModelBinder(mbc => { if (mbc.ModelType == typeof(int) && success) { var model = 42; return ModelBindingResult.Success(model); } return ModelBindingResult.Failed(); }); return mockIntBinder; }
public async Task TryBindStrongModel_InnerBinderReturnsAResult_ReturnsInnerBinderResult( object model, bool isSuccess) { // Arrange ModelBindingResult innerResult; if (isSuccess) { innerResult = ModelBindingResult.Success(model); } else { innerResult = ModelBindingResult.Failed(); } var innerBinder = new StubModelBinder(context => { Assert.Equal("someName.Key", context.ModelName); return innerResult; }); var valueProvider = new SimpleValueProvider(); var bindingContext = GetBindingContext(valueProvider, typeof(KeyValuePair<int, string>)); var binder = new KeyValuePairModelBinder<int, string>(innerBinder, innerBinder); // Act var result = await binder.TryBindStrongModel<int>(bindingContext, innerBinder, "Key", "someName.Key"); // Assert Assert.Equal(innerResult, result); Assert.Empty(bindingContext.ModelState); }
public async Task BindModelAsync_CreatesModel_IfIsTopLevelObject() { // Arrange var mockValueProvider = new Mock<IValueProvider>(); mockValueProvider .Setup(o => o.ContainsPrefix(It.IsAny<string>())) .Returns(false); // Mock binder fails to bind all properties. var mockBinder = new StubModelBinder(); var bindingContext = new DefaultModelBindingContext { IsTopLevelObject = true, ModelMetadata = GetMetadataForType(typeof(Person)), ModelName = string.Empty, ValueProvider = mockValueProvider.Object, ModelState = new ModelStateDictionary(), }; var model = new Person(); var testableBinder = new Mock<TestableComplexTypeModelBinder> { CallBase = true }; testableBinder .Setup(o => o.CreateModelPublic(bindingContext)) .Returns(model) .Verifiable(); testableBinder .Setup(o => o.CanBindPropertyPublic(bindingContext, It.IsAny<ModelMetadata>())) .Returns(false); // Act await testableBinder.Object.BindModelAsync(bindingContext); // Assert Assert.True(bindingContext.Result.IsModelSet); var returnedPerson = Assert.IsType<Person>(bindingContext.Result.Model); Assert.Same(model, returnedPerson); testableBinder.Verify(); }
public async Task BindSimpleCollection_SubBindingSucceeds() { // Arrange var culture = new CultureInfo("fr-FR"); var bindingContext = GetModelBindingContext(new SimpleValueProvider()); var elementBinder = new StubModelBinder(mbc => { Assert.Equal("someName", mbc.ModelName); mbc.Result = ModelBindingResult.Success(42); }); var modelBinder = new CollectionModelBinder<int>(elementBinder); // Act var boundCollection = await modelBinder.BindSimpleCollection( bindingContext, new ValueProviderResult(new string[] { "0" })); // Assert Assert.Equal(new[] { 42 }, boundCollection.Model.ToArray()); }