Пример #1
0
        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 void BindModel_MissingKey_ReturnsFalse()
        {
            // Arrange
            ControllerContext             controllerContext = new ControllerContext();
            ExtensibleModelBindingContext bindingContext    = new ExtensibleModelBindingContext
            {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(
                    null,
                    typeof(KeyValuePair <int, string>)
                    ),
                ModelName            = "someName",
                ModelBinderProviders = new ModelBinderProviderCollection(),
                ValueProvider        = new SimpleValueProvider()
            };

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

            // Act
            bool retVal = binder.BindModel(controllerContext, bindingContext);

            // Assert
            Assert.False(retVal);
            Assert.Null(bindingContext.Model);
            Assert.Empty(bindingContext.ValidationNode.ChildNodes);
        }
Пример #3
0
        public async Task TryBindStrongModel_BinderExists_BinderReturnsIncorrectlyTypedObject_ReturnsTrue()
        {
            // Arrange
            var innerBinder = new Mock <IModelBinder>();

            innerBinder
            .Setup(o => o.BindModelAsync(It.IsAny <ModelBindingContext>()))
            .Returns((ModelBindingContext mbc) =>
            {
                Assert.Equal("someName.key", mbc.ModelName);
                return(Task.FromResult(new ModelBindingResult(null, string.Empty, true)));
            });
            var bindingContext = GetBindingContext(new SimpleHttpValueProvider(), innerBinder.Object);


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

            // Act
            var result = await binder.TryBindStrongModel <int>(bindingContext, "key");

            // Assert
            Assert.True(result.IsModelSet);
            Assert.Null(result.Model);
            Assert.Empty(bindingContext.ModelState);
        }
        public void BindModel_MissingValue_ReturnsTrue() {
            // Arrange
            ControllerContext controllerContext = new ControllerContext();
            ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext() {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(KeyValuePair<int, string>)),
                ModelName = "someName",
                ModelBinderProviders = new ModelBinderProviderCollection(),
                ValueProvider = new SimpleValueProvider()
            };

            Mock<IExtensibleModelBinder> mockIntBinder = new Mock<IExtensibleModelBinder>();
            mockIntBinder
                .Setup(o => o.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
                .Returns(
                    delegate(ControllerContext cc, ExtensibleModelBindingContext mbc) {
                        mbc.Model = 42;
                        return true;
                    });
            bindingContext.ModelBinderProviders.RegisterBinderForType(typeof(int), mockIntBinder.Object, true /* suppressPrefixCheck */);

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

            // Act
            bool retVal = binder.BindModel(controllerContext, bindingContext);

            // Assert
            Assert.IsTrue(retVal, "Want to return 'True' since the key was bound correctly and we want to push validation up.");
            Assert.IsNull(bindingContext.Model);
            CollectionAssert.AreEquivalent(new string[] { "someName.key" },
                bindingContext.ValidationNode.ChildNodes.Select(n => n.ModelStateKey).ToArray());
        }
        public async Task KeyValuePairModelBinder_CreatesEmptyCollection_IfIsTopLevelObject()
        {
            // Arrange
            var binder = new KeyValuePairModelBinder <string, string>();

            var context = CreateContext();

            context.IsTopLevelObject = true;

            // Lack of prefix and non-empty model name both ignored.
            context.ModelName = "modelName";

            var metadataProvider = context.OperationBindingContext.MetadataProvider;

            context.ModelMetadata = metadataProvider.GetMetadataForType(typeof(KeyValuePair <string, string>));

            context.ValueProvider = new TestValueProvider(new Dictionary <string, object>());

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

            // Assert
            Assert.NotEqual(ModelBindingResult.NoResult, result);

            var model = Assert.IsType <KeyValuePair <string, string> >(result.Model);

            Assert.Equal(default(KeyValuePair <string, string>), model);
            Assert.Equal("modelName", result.Key);
            Assert.True(result.IsModelSet);
        }
Пример #6
0
        public async Task KeyValuePairModelBinder_DoesNotCreateCollection_IfIsTopLevelObjectAndIsFirstChanceBinding()
        {
            // Arrange
            var binder = new KeyValuePairModelBinder <string, string>();

            var context = CreateContext();

            context.IsTopLevelObject     = true;
            context.IsFirstChanceBinding = true;

            // Explicit prefix and empty model name both ignored.
            context.BinderModelName = "prefix";
            context.ModelName       = string.Empty;

            var metadataProvider = context.OperationBindingContext.MetadataProvider;

            context.ModelMetadata = metadataProvider.GetMetadataForType(typeof(KeyValuePair <string, string>));

            context.ValueProvider = new TestValueProvider(new Dictionary <string, object>());

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

            // Assert
            Assert.Null(result);
        }
Пример #7
0
        public async Task TryBindStrongModel_InnerBinderReturnsNotNull_ReturnsInnerBinderResult(
            object model,
            bool isModelSet)
        {
            // Arrange
            var innerResult = new ModelBindingResult(model, key: string.Empty, isModelSet: isModelSet);
            var innerBinder = new Mock <IModelBinder>();

            innerBinder
            .Setup(o => o.BindModelAsync(It.IsAny <ModelBindingContext>()))
            .Returns((ModelBindingContext context) =>
            {
                Assert.Equal("someName.key", context.ModelName);
                return(Task.FromResult(innerResult));
            });
            var bindingContext = GetBindingContext(new SimpleHttpValueProvider(), innerBinder.Object);

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

            // Act
            var result = await binder.TryBindStrongModel <int>(bindingContext, "key", modelValidationNodeList);

            // Assert
            Assert.Same(innerResult, result);
            Assert.Empty(bindingContext.ModelState);
        }
        public void BindModel_MissingValue_ReturnsTrue()
        {
            // Arrange
            Mock<IModelBinder> mockIntBinder = new Mock<IModelBinder>();
            ModelBindingContext bindingContext = new ModelBindingContext
            {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(KeyValuePair<int, string>)),
                ModelName = "someName",
                ValueProvider = new SimpleHttpValueProvider()
            };
            HttpActionContext context = ContextUtil.CreateActionContext();
            context.ControllerContext.Configuration.ServiceResolver.SetService(typeof(ModelBinderProvider), new SimpleModelBinderProvider(typeof(int), mockIntBinder.Object) { SuppressPrefixCheck = true });

            mockIntBinder
                .Setup(o => o.BindModel(context, It.IsAny<ModelBindingContext>()))
                .Returns((HttpActionContext cc, ModelBindingContext mbc) =>
                {
                    mbc.Model = 42;
                    return true;
                });
            KeyValuePairModelBinder<int, string> binder = new KeyValuePairModelBinder<int, string>();

            // Act
            bool retVal = binder.BindModel(context, bindingContext);

            // Assert
            Assert.True(retVal);
            Assert.Null(bindingContext.Model);
            Assert.Equal(new[] { "someName.key" }, bindingContext.ValidationNode.ChildNodes.Select(n => n.ModelStateKey).ToArray());
        }
        public void BindModel_MissingValue_ReturnsTrue()
        {
            // Arrange
            ControllerContext             controllerContext = new ControllerContext();
            ExtensibleModelBindingContext bindingContext    = new ExtensibleModelBindingContext
            {
                ModelMetadata        = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(KeyValuePair <int, string>)),
                ModelName            = "someName",
                ModelBinderProviders = new ModelBinderProviderCollection(),
                ValueProvider        = new SimpleValueProvider()
            };

            Mock <IExtensibleModelBinder> mockIntBinder = new Mock <IExtensibleModelBinder>();

            mockIntBinder
            .Setup(o => o.BindModel(controllerContext, It.IsAny <ExtensibleModelBindingContext>()))
            .Returns(
                delegate(ControllerContext cc, ExtensibleModelBindingContext mbc)
            {
                mbc.Model = 42;
                return(true);
            });
            bindingContext.ModelBinderProviders.RegisterBinderForType(typeof(int), mockIntBinder.Object, true /* suppressPrefixCheck */);

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

            // Act
            bool retVal = binder.BindModel(controllerContext, bindingContext);

            // Assert
            Assert.True(retVal);
            Assert.Null(bindingContext.Model);
            Assert.Equal(new[] { "someName.key" }, bindingContext.ValidationNode.ChildNodes.Select(n => n.ModelStateKey).ToArray());
        }
Пример #10
0
    public async Task BindModel_MissingValue_ReturnsResult_AndAddsModelValidationError()
    {
        // Arrange
        var valueProvider = new SimpleValueProvider();

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

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.Null(bindingContext.Result.Model);
        Assert.False(bindingContext.ModelState.IsValid);
        Assert.Equal("someName", bindingContext.ModelName);
        var state = bindingContext.ModelState["someName.Value"];

        Assert.NotNull(state);
        var error = Assert.Single(state.Errors);

        Assert.Equal("A value is required.", error.ErrorMessage);
    }
        public async Task TryBindStrongModel_InnerBinderReturnsAResult_ReturnsInnerBinderResult(
            object model,
            bool isSuccess)
        {
            // Arrange
            ModelBindingResult?innerResult;

            if (isSuccess)
            {
                innerResult = ModelBindingResult.Success("somename.key", model);
            }
            else
            {
                innerResult = ModelBindingResult.Failed("somename.key");
            }

            var innerBinder = new StubModelBinder(context =>
            {
                Assert.Equal("someName.key", context.ModelName);
                return(innerResult);
            });
            var bindingContext = GetBindingContext(new SimpleValueProvider(), innerBinder);

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

            // Act
            var result = await binder.TryBindStrongModel <int>(bindingContext, "key");

            // Assert
            Assert.Equal(innerResult.Value, result);
            Assert.Empty(bindingContext.ModelState);
        }
Пример #12
0
    public async Task KeyValuePairModelBinder_DoesNotCreateCollection_IfNotIsTopLevelObject(string prefix)
    {
        // Arrange
        var binder = new KeyValuePairModelBinder <string, string>(
            new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
            new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
            NullLoggerFactory.Instance);

        var bindingContext = CreateContext();

        bindingContext.ModelName = ModelNames.CreatePropertyModelName(prefix, "KeyValuePairProperty");

        var metadataProvider = new TestModelMetadataProvider();

        bindingContext.ModelMetadata = metadataProvider.GetMetadataForProperty(
            typeof(ModelWithKeyValuePairProperty),
            nameof(ModelWithKeyValuePairProperty.KeyValuePairProperty));

        bindingContext.ValueProvider = new TestValueProvider(new Dictionary <string, object>());

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.False(bindingContext.Result.IsModelSet);
    }
Пример #13
0
        public async Task KeyValuePairModelBinder_CreatesEmptyCollection_ForTopLevelModel_WithExplicitPrefix()
        {
            // Arrange
            var binder = new KeyValuePairModelBinder <string, string>();

            var context = CreateContext();

            context.ModelName       = "prefix";
            context.BinderModelName = "prefix";

            var metadataProvider = context.OperationBindingContext.MetadataProvider;

            context.ModelMetadata = metadataProvider.GetMetadataForType(typeof(KeyValuePair <string, string>));

            context.ValueProvider = new TestValueProvider(new Dictionary <string, object>());

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

            // Assert
            Assert.NotNull(result);

            Assert.Equal(default(KeyValuePair <string, string>), Assert.IsType <KeyValuePair <string, string> >(result.Model));
            Assert.Equal("prefix", result.Key);
            Assert.True(result.IsModelSet);

            Assert.Equal(result.ValidationNode.Model, result.Model);
            Assert.Same(result.ValidationNode.Key, result.Key);
            Assert.Same(result.ValidationNode.ModelMetadata, context.ModelMetadata);
        }
Пример #14
0
    public async Task KeyValuePairModelBinder_CreatesEmptyCollection_IfIsTopLevelObject()
    {
        // Arrange
        var binder = new KeyValuePairModelBinder <string, string>(
            new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
            new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
            NullLoggerFactory.Instance);

        var bindingContext = CreateContext();

        bindingContext.IsTopLevelObject = true;

        // Lack of prefix and non-empty model name both ignored.
        bindingContext.ModelName = "modelName";

        var metadataProvider = new TestModelMetadataProvider();

        bindingContext.ModelMetadata = metadataProvider.GetMetadataForType(typeof(KeyValuePair <string, string>));

        bindingContext.ValueProvider = new TestValueProvider(new Dictionary <string, object>());

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        var model = Assert.IsType <KeyValuePair <string, string> >(bindingContext.Result.Model);

        Assert.Equal(default(KeyValuePair <string, string>), model);
        Assert.True(bindingContext.Result.IsModelSet);
    }
Пример #15
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);
    }
Пример #16
0
    public async Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException(nameof(bindingContext));
        }

        _logger.AttemptingToBindModel(bindingContext);

        var keyModelName = ModelNames.CreatePropertyModelName(bindingContext.ModelName, "Key");
        var keyResult    = await KeyValuePairModelBinder <TKey, TValue> .TryBindStrongModel <TKey?>(bindingContext, _keyBinder, "Key", keyModelName);

        var valueModelName = ModelNames.CreatePropertyModelName(bindingContext.ModelName, "Value");
        var valueResult    = await KeyValuePairModelBinder <TKey, TValue> .TryBindStrongModel <TValue?>(bindingContext, _valueBinder, "Value", valueModelName);

        if (keyResult.IsModelSet && valueResult.IsModelSet)
        {
            var model = new KeyValuePair <TKey?, TValue?>(
                ModelBindingHelper.CastOrDefault <TKey?>(keyResult.Model),
                ModelBindingHelper.CastOrDefault <TValue?>(valueResult.Model));

            bindingContext.Result = ModelBindingResult.Success(model);
            _logger.DoneAttemptingToBindModel(bindingContext);
            return;
        }

        if (!keyResult.IsModelSet && valueResult.IsModelSet)
        {
            bindingContext.ModelState.TryAddModelError(
                keyModelName,
                bindingContext.ModelMetadata.ModelBindingMessageProvider.MissingKeyOrValueAccessor());
            _logger.DoneAttemptingToBindModel(bindingContext);
            return;
        }

        if (keyResult.IsModelSet && !valueResult.IsModelSet)
        {
            bindingContext.ModelState.TryAddModelError(
                valueModelName,
                bindingContext.ModelMetadata.ModelBindingMessageProvider.MissingKeyOrValueAccessor());
            _logger.DoneAttemptingToBindModel(bindingContext);
            return;
        }

        // If we failed to find data for a top-level model, then generate a
        // default 'empty' model and return it.
        if (bindingContext.IsTopLevelObject)
        {
            var model = new KeyValuePair <TKey?, TValue?>();
            bindingContext.Result = ModelBindingResult.Success(model);
        }
        _logger.DoneAttemptingToBindModel(bindingContext);
    }
Пример #17
0
        public async Task TryBindStrongModel_BinderExists_BinderReturnsCorrectlyTypedObject_ReturnsTrue()
        {
            // Arrange
            ModelBindingContext bindingContext = GetBindingContext(new SimpleHttpValueProvider());
            var binder = new KeyValuePairModelBinder <int, string>();

            // Act
            var result = await binder.TryBindStrongModel <int>(bindingContext, "key");

            // Assert
            Assert.True(result.IsModelSet);
            Assert.Equal(42, result.Model);
            Assert.Empty(bindingContext.ModelState);
        }
Пример #18
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);
        }
Пример #19
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());
        }
Пример #20
0
        public async Task TryBindStrongModel_BinderExists_BinderReturnsCorrectlyTypedObject_ReturnsTrue()
        {
            // Arrange
            ModelBindingContext bindingContext = GetBindingContext(new SimpleHttpValueProvider());
            var binder = new KeyValuePairModelBinder<int, string>();

            // Act
            var retVal = await binder.TryBindStrongModel<int>(bindingContext, "key");

            // Assert
            Assert.True(retVal.Success);
            Assert.Equal(42, retVal.Model);
            Assert.Single(bindingContext.ValidationNode.ChildNodes);
            Assert.Empty(bindingContext.ModelState);
        }
Пример #21
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());
        }
Пример #22
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 BindModel_SubBindingSucceeds()
        {
            // Arrange
            var innerBinder    = new CompositeModelBinder(new[] { CreateStringBinder(), CreateIntBinder() });
            var valueProvider  = new SimpleValueProvider();
            var bindingContext = GetBindingContext(valueProvider, innerBinder);

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

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

            // Assert
            Assert.NotEqual(ModelBindingResult.NoResult, result);
            Assert.Equal(new KeyValuePair <int, string>(42, "some-value"), result.Model);
        }
Пример #24
0
        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 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());
        }
Пример #25
0
        public async Task BindModel_MissingKeyAndMissingValue_DoNotAddModelStateError()
        {
            // Arrange
            var valueProvider = new SimpleValueProvider();

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

            // Act
            await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.False(bindingContext.Result.IsModelSet);
            Assert.True(bindingContext.ModelState.IsValid);
            Assert.Equal(0, bindingContext.ModelState.ErrorCount);
        }
Пример #26
0
    public async Task BindModel_SubBindingSucceeds()
    {
        // Arrange
        var valueProvider = new SimpleValueProvider();

        var bindingContext = GetBindingContext(valueProvider, typeof(KeyValuePair <int, string>));
        var binder         = new KeyValuePairModelBinder <int, string>(
            CreateIntBinder(),
            CreateStringBinder(),
            NullLoggerFactory.Instance);

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.True(bindingContext.Result.IsModelSet);
        Assert.Equal(new KeyValuePair <int, string>(42, "some-value"), bindingContext.Result.Model);
    }
Пример #27
0
        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_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 void BindModel_MissingKey_ReturnsFalse() {
            // Arrange
            ControllerContext controllerContext = new ControllerContext();
            ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext() {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(KeyValuePair<int, string>)),
                ModelName = "someName",
                ModelBinderProviders = new ModelBinderProviderCollection(),
                ValueProvider = new SimpleValueProvider()
            };

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

            // Act
            bool retVal = binder.BindModel(controllerContext, bindingContext);

            // Assert
            Assert.IsFalse(retVal);
            Assert.IsNull(bindingContext.Model);
            Assert.AreEqual(0, bindingContext.ValidationNode.ChildNodes.Count, "No child nodes should have been added.");
        }
        public async Task BindModel_MissingKeyAndMissingValue_DoNotAddModelStateError()
        {
            // Arrange
            var valueProvider = new SimpleValueProvider();

            // Create int binder to create the value but not the key.
            var bindingContext = GetBindingContext(valueProvider);
            var mockBinder     = new StubModelBinder();

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

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

            // Assert
            Assert.Equal(default(ModelBindingResult), result);
            Assert.True(bindingContext.ModelState.IsValid);
            Assert.Equal(0, bindingContext.ModelState.ErrorCount);
        }
Пример #31
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());
        }
Пример #32
0
    public async Task BindModel_MissingKeyAndMissingValue_DoNotAddModelStateError()
    {
        // Arrange
        var valueProvider = new SimpleValueProvider();

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

        // Act
        await binder.BindModelAsync(bindingContext);

        // Assert
        Assert.False(bindingContext.Result.IsModelSet);
        Assert.True(bindingContext.ModelState.IsValid);
        Assert.Equal(0, bindingContext.ModelState.ErrorCount);
    }
Пример #33
0
        public async Task BindModel_MissingKey_ReturnsResult_AndAddsModelValidationError()
        {
            // Arrange
            var valueProvider = new SimpleValueProvider();

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

            // Act
            await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.False(bindingContext.Result.IsModelSet);
            Assert.Null(bindingContext.Result.Model);
            Assert.False(bindingContext.ModelState.IsValid);
            Assert.Equal("someName", bindingContext.ModelName);
            var error = Assert.Single(bindingContext.ModelState["someName.Key"].Errors);
            Assert.Equal("A value is required.", error.ErrorMessage);
        }
Пример #34
0
        public async Task KeyValuePairModelBinder_DoesNotCreateCollection_ForTopLevelModel_OnFirstPass()
        {
            // Arrange
            var binder = new KeyValuePairModelBinder <string, string>();

            var context = CreateContext();

            context.ModelName = "param";

            var metadataProvider = context.OperationBindingContext.MetadataProvider;

            context.ModelMetadata = metadataProvider.GetMetadataForType(typeof(KeyValuePair <string, string>));

            context.ValueProvider = new TestValueProvider(new Dictionary <string, object>());

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

            // Assert
            Assert.Null(result);
        }
        public void BindModel_MissingKey_ReturnsFalse()
        {
            // Arrange
            KeyValuePairModelBinder<int, string> binder = new KeyValuePairModelBinder<int, string>();
            ModelBindingContext bindingContext = new ModelBindingContext
            {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(KeyValuePair<int, string>)),
                ModelName = "someName",
                ValueProvider = new SimpleHttpValueProvider()
            };
            HttpActionContext context = ContextUtil.CreateActionContext();
            context.ControllerContext.Configuration.ServiceResolver.SetService(typeof(ModelBinderProvider), new SimpleModelBinderProvider(typeof(KeyValuePair<int, string>), binder));

            // Act
            bool retVal = binder.BindModel(context, bindingContext);

            // Assert
            Assert.False(retVal);
            Assert.Null(bindingContext.Model);
            Assert.Empty(bindingContext.ValidationNode.ChildNodes);
        }
        public async Task BindModel_MissingKey_ReturnsResult_AndAddsModelValidationError()
        {
            // Arrange
            var valueProvider = new SimpleValueProvider();

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

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

            // Assert
            Assert.NotEqual(ModelBindingResult.NoResult, result);
            Assert.Null(result.Model);
            Assert.False(bindingContext.ModelState.IsValid);
            Assert.Equal("someName", bindingContext.ModelName);
            var error = Assert.Single(bindingContext.ModelState["someName.Key"].Errors);

            Assert.Equal("A value is required.", error.ErrorMessage);
        }
        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);
        }
Пример #38
0
        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 KeyValuePairModelBinder_DoesNotCreateCollection_IfNotIsTopLevelObject(string prefix)
        {
            // Arrange
            var binder = new KeyValuePairModelBinder <string, string>();

            var context = CreateContext();

            context.ModelName = ModelNames.CreatePropertyModelName(prefix, "KeyValuePairProperty");

            var metadataProvider = context.OperationBindingContext.MetadataProvider;

            context.ModelMetadata = metadataProvider.GetMetadataForProperty(
                typeof(ModelWithKeyValuePairProperty),
                nameof(ModelWithKeyValuePairProperty.KeyValuePairProperty));

            context.ValueProvider = new TestValueProvider(new Dictionary <string, object>());

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

            // Assert
            Assert.Equal(ModelBindingResult.NoResult, result);
        }
        public async Task TryBindStrongModel_InnerBinderReturnsAResult_ReturnsInnerBinderResult(
            object model,
            bool isSuccess)
        {
            // Arrange
            ModelBindingResult innerResult;

            if (isSuccess)
            {
                innerResult = ModelBindingResult.Success("somename.key", model);
            }
            else
            {
                innerResult = ModelBindingResult.Failed("somename.key");
            }

            var innerBinder = new Mock <IModelBinder>();

            innerBinder
            .Setup(o => o.BindModelAsync(It.IsAny <ModelBindingContext>()))
            .Returns((ModelBindingContext context) =>
            {
                Assert.Equal("someName.key", context.ModelName);
                return(Task.FromResult(innerResult));
            });
            var bindingContext = GetBindingContext(new SimpleValueProvider(), innerBinder.Object);

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

            // Act
            var result = await binder.TryBindStrongModel <int>(bindingContext, "key");

            // Assert
            Assert.Equal(innerResult, result);
            Assert.Empty(bindingContext.ModelState);
        }
Пример #41
0
        public async Task KeyValuePairModelBinder_DoesNotCreateCollection_IfIsTopLevelObjectAndIsFirstChanceBinding()
        {
            // Arrange
            var binder = new KeyValuePairModelBinder<string, string>();

            var context = CreateContext();
            context.IsTopLevelObject = true;
            context.IsFirstChanceBinding = true;

            // Explicit prefix and empty model name both ignored.
            context.BinderModelName = "prefix";
            context.ModelName = string.Empty;

            var metadataProvider = context.OperationBindingContext.MetadataProvider;
            context.ModelMetadata = metadataProvider.GetMetadataForType(typeof(KeyValuePair<string, string>));

            context.ValueProvider = new TestValueProvider(new Dictionary<string, object>());

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

            // Assert
            Assert.Null(result);
        }
        public async Task TryBindStrongModel_InnerBinderReturnsAResult_ReturnsInnerBinderResult(
            object model,
            bool isSuccess)
        {
            // Arrange
            ModelBindingResult innerResult;
            if (isSuccess)
            {
                innerResult = ModelBindingResult.Success("somename.key", model);
            }
            else
            {
                innerResult = ModelBindingResult.Failed("somename.key");
            }

            var innerBinder = new Mock<IModelBinder>();
            innerBinder
                .Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
                .Returns((ModelBindingContext context) =>
                {
                    Assert.Equal("someName.key", context.ModelName);
                    return Task.FromResult(innerResult);
                });
            var bindingContext = GetBindingContext(new SimpleValueProvider(), innerBinder.Object);

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

            // Act
            var result = await binder.TryBindStrongModel<int>(bindingContext, "key");

            // Assert
            Assert.Equal(innerResult, result);
            Assert.Empty(bindingContext.ModelState);
        }
        public async Task KeyValuePairModelBinder_CreatesEmptyCollection_IfIsTopLevelObject()
        {
            // Arrange
            var binder = new KeyValuePairModelBinder<string, string>();

            var context = CreateContext();
            context.IsTopLevelObject = true;

            // Lack of prefix and non-empty model name both ignored.
            context.ModelName = "modelName";

            var metadataProvider = context.OperationBindingContext.MetadataProvider;
            context.ModelMetadata = metadataProvider.GetMetadataForType(typeof(KeyValuePair<string, string>));

            context.ValueProvider = new TestValueProvider(new Dictionary<string, object>());

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

            // Assert
            Assert.NotEqual(ModelBindingResult.NoResult, result);

            var model = Assert.IsType<KeyValuePair<string, string>>(result.Model);
            Assert.Equal(default(KeyValuePair<string, string>), model);
            Assert.Equal("modelName", result.Key);
            Assert.True(result.IsModelSet);
        }
        public async Task BindModel_SubBindingSucceeds()
        {
            // Arrange
            var innerBinder = new CompositeModelBinder(new[] { CreateStringBinder(), CreateIntBinder() });
            var valueProvider = new SimpleValueProvider();
            var bindingContext = GetBindingContext(valueProvider, innerBinder);

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

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

            // Assert
            Assert.NotEqual(ModelBindingResult.NoResult, result);
            Assert.Equal(new KeyValuePair<int, string>(42, "some-value"), result.Model);
        }
        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);
        }
Пример #46
0
        public async Task TryBindStrongModel_BinderExists_BinderReturnsIncorrectlyTypedObject_ReturnsTrue()
        {
            // Arrange
            var innerBinder = new Mock<IModelBinder>();
            innerBinder
                .Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
                .Returns((ModelBindingContext mbc) =>
                {
                    Assert.Equal("someName.key", mbc.ModelName);
                    return Task.FromResult(true);
                });
            var bindingContext = GetBindingContext(new SimpleHttpValueProvider(), innerBinder.Object);
            

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

            // Act
            var retVal = await binder.TryBindStrongModel<int>(bindingContext, "key");

            // Assert
            Assert.True(retVal.Success);
            Assert.Equal(default(int), retVal.Model);
            Assert.Single(bindingContext.ValidationNode.ChildNodes);
            Assert.Empty(bindingContext.ModelState);
        }
Пример #47
0
        public async Task KeyValuePairModelBinder_CreatesEmptyCollection_IfIsTopLevelObject()
        {
            // Arrange
            var binder = new KeyValuePairModelBinder<string, string>(
                new SimpleTypeModelBinder(typeof(string)), 
                new SimpleTypeModelBinder(typeof(string)));

            var bindingContext = CreateContext();
            bindingContext.IsTopLevelObject = true;

            // Lack of prefix and non-empty model name both ignored.
            bindingContext.ModelName = "modelName";

            var metadataProvider = new TestModelMetadataProvider();
            bindingContext.ModelMetadata = metadataProvider.GetMetadataForType(typeof(KeyValuePair<string, string>));

            bindingContext.ValueProvider = new TestValueProvider(new Dictionary<string, object>());

            // Act
            await binder.BindModelAsync(bindingContext);

            // Assert
            var model = Assert.IsType<KeyValuePair<string, string>>(bindingContext.Result.Model);
            Assert.Equal(default(KeyValuePair<string, string>), model);
            Assert.True(bindingContext.Result.IsModelSet);
        }
Пример #48
0
        public async Task KeyValuePairModelBinder_DoesNotCreateCollection_IfNotIsTopLevelObject(string prefix)
        {
            // Arrange
            var binder = new KeyValuePairModelBinder<string, string>(
                new SimpleTypeModelBinder(typeof(string)), 
                new SimpleTypeModelBinder(typeof(string)));

            var bindingContext = CreateContext();
            bindingContext.ModelName = ModelNames.CreatePropertyModelName(prefix, "KeyValuePairProperty");

            var metadataProvider = new TestModelMetadataProvider();
            bindingContext.ModelMetadata = metadataProvider.GetMetadataForProperty(
                typeof(ModelWithKeyValuePairProperty),
                nameof(ModelWithKeyValuePairProperty.KeyValuePairProperty));

            bindingContext.ValueProvider = new TestValueProvider(new Dictionary<string, object>());

            // Act
            await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.False(bindingContext.Result.IsModelSet);
        }
Пример #49
0
        public async Task BindModel_SubBindingSucceeds()
        {
            // Arrange
            var valueProvider = new SimpleValueProvider();

            var bindingContext = GetBindingContext(valueProvider, typeof(KeyValuePair<int, string>));
            var binder = new KeyValuePairModelBinder<int, string>(CreateIntBinder(), CreateStringBinder());

            // Act
            await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.True(bindingContext.Result.IsModelSet);
            Assert.Equal(new KeyValuePair<int, string>(42, "some-value"), bindingContext.Result.Model);
        }
        public async Task KeyValuePairModelBinder_DoesNotCreateCollection_ForTopLevelModel_OnFirstPass()
        {
            // Arrange
            var binder = new KeyValuePairModelBinder<string, string>();

            var context = CreateContext();
            context.ModelName = "param";

            var metadataProvider = context.OperationBindingContext.MetadataProvider;
            context.ModelMetadata = metadataProvider.GetMetadataForType(typeof(KeyValuePair<string, string>));

            context.ValueProvider = new TestValueProvider(new Dictionary<string, object>());

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

            // Assert
            Assert.Null(result);
        }
        public async Task KeyValuePairModelBinder_CreatesEmptyCollection_ForTopLevelModel_WithExplicitPrefix()
        {
            // Arrange
            var binder = new KeyValuePairModelBinder<string, string>();

            var context = CreateContext();
            context.ModelName = "prefix";
            context.BinderModelName = "prefix";

            var metadataProvider = context.OperationBindingContext.MetadataProvider;
            context.ModelMetadata = metadataProvider.GetMetadataForType(typeof(KeyValuePair<string, string>));

            context.ValueProvider = new TestValueProvider(new Dictionary<string, object>());

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

            // Assert
            Assert.NotNull(result);

            Assert.Equal(default(KeyValuePair<string, string>), Assert.IsType<KeyValuePair<string, string>>(result.Model));
            Assert.Equal("prefix", result.Key);
            Assert.True(result.IsModelSet);

            Assert.Equal(result.ValidationNode.Model, result.Model);
            Assert.Same(result.ValidationNode.Key, result.Key);
            Assert.Same(result.ValidationNode.ModelMetadata, context.ModelMetadata);
        }
        public async Task KeyValuePairModelBinder_DoesNotCreateCollection_ForNonTopLevelModel(string prefix)
        {
            // Arrange
            var binder = new KeyValuePairModelBinder<string, string>();

            var context = CreateContext();
            context.ModelName = ModelNames.CreatePropertyModelName(prefix, "KeyValuePairProperty");

            var metadataProvider = context.OperationBindingContext.MetadataProvider;
            context.ModelMetadata = metadataProvider.GetMetadataForProperty(
                typeof(ModelWithKeyValuePairProperty),
                nameof(ModelWithKeyValuePairProperty.KeyValuePairProperty));

            context.ValueProvider = new TestValueProvider(new Dictionary<string, object>());

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

            // Assert
            Assert.Null(result);
        }
Пример #53
0
        public async Task TryBindStrongModel_BinderExists_BinderReturnsIncorrectlyTypedObject_ReturnsTrue()
        {
            // Arrange
            var innerBinder = new Mock<IModelBinder>();
            innerBinder
                .Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
                .Returns((ModelBindingContext mbc) =>
                {
                    Assert.Equal("someName.key", mbc.ModelName);
                    return Task.FromResult(new ModelBindingResult(null, string.Empty, true));
                });
            var bindingContext = GetBindingContext(new SimpleHttpValueProvider(), innerBinder.Object);


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

            // Act
            var result = await binder.TryBindStrongModel<int>(bindingContext, "key", modelValidationNodeList);

            // Assert
            Assert.True(result.IsModelSet);
            Assert.Null(result.Model);
            Assert.Empty(bindingContext.ModelState);
        }
Пример #54
0
        public async Task TryBindStrongModel_BinderExists_BinderReturnsCorrectlyTypedObject_ReturnsTrue()
        {
            // Arrange
            var bindingContext = GetBindingContext(new SimpleHttpValueProvider());
            var binder = new KeyValuePairModelBinder<int, string>();
            var modelValidationNodeList = new List<ModelValidationNode>();

            // Act
            var result = await binder.TryBindStrongModel<int>(bindingContext, "key", modelValidationNodeList);

            // Assert
            Assert.True(result.IsModelSet);
            Assert.Equal(42, result.Model);
            Assert.Empty(bindingContext.ModelState);
        }
Пример #55
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);

            // Act
            var result = await binder.TryBindStrongModel<int>(bindingContext, innerBinder, "Key", "someName.Key");

            // Assert
            Assert.Equal(innerResult, result);
            Assert.Empty(bindingContext.ModelState);
        }
        public async Task TryBindStrongModel_InnerBinderReturnsNotNull_ReturnsInnerBinderResult(
            object model,
            bool isModelSet)
        {
            // Arrange
            var innerResult = new ModelBindingResult(model, key: string.Empty, isModelSet: isModelSet);
            var innerBinder = new Mock<IModelBinder>();
            innerBinder
                .Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
                .Returns((ModelBindingContext context) =>
                {
                    Assert.Equal("someName.key", context.ModelName);
                    return Task.FromResult(innerResult);
                });
            var bindingContext = GetBindingContext(new SimpleHttpValueProvider(), innerBinder.Object);

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

            // Act
            var result = await binder.TryBindStrongModel<int>(bindingContext, "key", modelValidationNodeList);

            // Assert
            Assert.Same(innerResult, result);
            Assert.Empty(bindingContext.ModelState);
        }
        public void BindModel_SubBindingSucceeds() {
            // Arrange
            ControllerContext controllerContext = new ControllerContext();
            ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext() {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(KeyValuePair<int, string>)),
                ModelName = "someName",
                ModelBinderProviders = new ModelBinderProviderCollection(),
                ValueProvider = new SimpleValueProvider()
            };

            Mock<IExtensibleModelBinder> mockIntBinder = new Mock<IExtensibleModelBinder>();
            mockIntBinder
                .Setup(o => o.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
                .Returns(
                    delegate(ControllerContext cc, ExtensibleModelBindingContext mbc) {
                        mbc.Model = 42;
                        return true;
                    });
            bindingContext.ModelBinderProviders.RegisterBinderForType(typeof(int), mockIntBinder.Object, true /* suppressPrefixCheck */);
            Mock<IExtensibleModelBinder> mockStringBinder = new Mock<IExtensibleModelBinder>();
            mockStringBinder
                .Setup(o => o.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
                .Returns(
                    delegate(ControllerContext cc, ExtensibleModelBindingContext mbc) {
                        mbc.Model = "forty-two";
                        return true;
                    });
            bindingContext.ModelBinderProviders.RegisterBinderForType(typeof(string), mockStringBinder.Object, true /* suppressPrefixCheck */);

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

            // Act
            bool retVal = binder.BindModel(controllerContext, bindingContext);

            // Assert
            Assert.IsTrue(retVal);
            Assert.AreEqual(new KeyValuePair<int, string>(42, "forty-two"), bindingContext.Model);
            CollectionAssert.AreEquivalent(new string[] { "someName.key", "someName.value" },
                bindingContext.ValidationNode.ChildNodes.Select(n => n.ModelStateKey).ToArray());
        }