public async Task BindModelAsync_PassesExpectedBindingInfoAndMetadata_IfPrefixDoesNotMatch(
            BindingInfo parameterBindingInfo,
            string metadataBinderModelName,
            string parameterName,
            string expectedModelName)
        {
            // Arrange
            var metadataProvider = new TestModelMetadataProvider();

            metadataProvider.ForType <Person>().BindingDetails(binding =>
            {
                binding.BinderModelName = metadataBinderModelName;
            });

            var metadata    = metadataProvider.GetMetadataForType(typeof(Person));
            var modelBinder = new Mock <IModelBinder>();

            modelBinder
            .Setup(b => b.BindModelAsync(It.IsAny <ModelBindingContext>()))
            .Callback((ModelBindingContext context) =>
            {
                Assert.Equal(expectedModelName, context.ModelName, StringComparer.Ordinal);
            })
            .Returns(TaskCache.CompletedTask);

            var parameterDescriptor = new ParameterDescriptor
            {
                BindingInfo   = parameterBindingInfo,
                Name          = parameterName,
                ParameterType = typeof(Person),
            };

            var factory = new Mock <IModelBinderFactory>(MockBehavior.Strict);

            factory
            .Setup(f => f.CreateBinder(It.IsAny <ModelBinderFactoryContext>()))
            .Callback((ModelBinderFactoryContext context) =>
            {
                // Confirm expected data is passed through to ModelBindingFactory.
                Assert.Same(parameterDescriptor.BindingInfo, context.BindingInfo);
                Assert.Same(parameterDescriptor, context.CacheToken);
                Assert.Equal(metadata, context.Metadata);
            })
            .Returns(modelBinder.Object);

            var argumentBinder = new DefaultControllerArgumentBinder(
                metadataProvider,
                factory.Object,
                CreateMockValidator());

            var controllerContext = GetControllerContext();

            controllerContext.ActionDescriptor.Parameters.Add(parameterDescriptor);

            // Act & Assert
            await argumentBinder.BindModelAsync(parameterDescriptor, controllerContext);
        }
        public async Task BindModelAsync_PassesExpectedBindingInfoAndMetadata_IfPrefixMatches()
        {
            // Arrange
            var expectedModelName = "expectedName";

            var metadataProvider = new TestModelMetadataProvider();
            var metadata         = metadataProvider.GetMetadataForType(typeof(Person));
            var modelBinder      = new Mock <IModelBinder>();

            modelBinder
            .Setup(b => b.BindModelAsync(It.IsAny <ModelBindingContext>()))
            .Callback((ModelBindingContext context) =>
            {
                Assert.Equal(expectedModelName, context.ModelName, StringComparer.Ordinal);
            })
            .Returns(TaskCache.CompletedTask);

            var parameterDescriptor = new ParameterDescriptor
            {
                Name          = expectedModelName,
                ParameterType = typeof(Person),
            };

            var factory = new Mock <IModelBinderFactory>(MockBehavior.Strict);

            factory
            .Setup(f => f.CreateBinder(It.IsAny <ModelBinderFactoryContext>()))
            .Callback((ModelBinderFactoryContext context) =>
            {
                // Confirm expected data is passed through to ModelBindingFactory.
                Assert.Null(context.BindingInfo);
                Assert.Same(parameterDescriptor, context.CacheToken);
                Assert.Equal(metadata, context.Metadata);
            })
            .Returns(modelBinder.Object);

            var argumentBinder = new DefaultControllerArgumentBinder(
                metadataProvider,
                factory.Object,
                CreateMockValidator());

            var valueProvider = new SimpleValueProvider
            {
                { expectedModelName, new object() },
            };
            var valueProviderFactory = new SimpleValueProviderFactory(valueProvider);

            var controllerContext = GetControllerContext();

            controllerContext.ActionDescriptor.Parameters.Add(parameterDescriptor);
            controllerContext.ValueProviderFactories.Insert(0, valueProviderFactory);

            // Act & Assert
            await argumentBinder.BindModelAsync(parameterDescriptor, controllerContext);
        }