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);
        }
Example #3
0
    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);
    }
Example #4
0
        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);
        }
Example #5
0
        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"]);
        }
Example #6
0
    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);
    }
Example #7
0
        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();
        }
Example #13
0
        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());
        }