Esempio n. 1
0
    public void CreateBinder_Caches_WhenTokenIsNotNull()
    {
        // Arrange
        var metadataProvider = new TestModelMetadataProvider();

        var options = Options.Create(new MvcOptions());

        options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c =>
        {
            Assert.Equal(typeof(Employee), c.Metadata.ModelType);
            return(Mock.Of <IModelBinder>());
        }));

        var factory = new ModelBinderFactory(
            metadataProvider,
            options,
            GetServices());

        var context = new ModelBinderFactoryContext()
        {
            Metadata   = metadataProvider.GetMetadataForType(typeof(Employee)),
            CacheToken = new object(),
        };

        // Act
        var result1 = factory.CreateBinder(context);
        var result2 = factory.CreateBinder(context);

        // Assert
        Assert.Same(result1, result2);
    }
Esempio n. 2
0
    public void CreateBinder_Caches_NonRootNodes_WhenNonRootNodeReturnsNull()
    {
        // Arrange
        var metadataProvider = new TestModelMetadataProvider();

        var options = Options.Create(new MvcOptions());

        IModelBinder inner = null;

        var widgetProvider = new TestModelBinderProvider(c =>
        {
            if (c.Metadata.ModelType == typeof(Widget))
            {
                var binder = c.CreateBinder(c.Metadata.Properties[nameof(Widget.Id)]);
                Assert.IsType <NoOpBinder>(binder);
                if (inner == null)
                {
                    inner = binder;
                }
                else
                {
                    Assert.Same(inner, binder);
                }

                return(Mock.Of <IModelBinder>());
            }

            return(null);
        });

        var widgetIdProvider = new TestModelBinderProvider(c =>
        {
            Assert.Equal(typeof(WidgetId), c.Metadata.ModelType);
            return(null);
        });

        options.Value.ModelBinderProviders.Add(widgetProvider);
        options.Value.ModelBinderProviders.Add(widgetIdProvider);

        var factory = new ModelBinderFactory(
            metadataProvider,
            options,
            GetServices());

        var context = new ModelBinderFactoryContext()
        {
            Metadata   = metadataProvider.GetMetadataForType(typeof(Widget)),
            CacheToken = null, // We want the outermost provider to run twice.
        };

        // Act
        var result1 = factory.CreateBinder(context);
        var result2 = factory.CreateBinder(context);

        // Assert
        Assert.NotSame(result1, result2);

        Assert.Equal(2, widgetProvider.SuccessCount);
        Assert.Equal(0, widgetIdProvider.SuccessCount);
    }
Esempio n. 3
0
    public void CreateBinder_CreatesNoOpBinder_WhenPropertyDoesntHaveABinder()
    {
        // Arrange
        var metadataProvider = new TestModelMetadataProvider();

        // There isn't a provider that can handle WidgetId.
        var options = Options.Create(new MvcOptions());

        options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c =>
        {
            if (c.Metadata.ModelType == typeof(Widget))
            {
                Assert.NotNull(c.CreateBinder(c.Metadata.Properties[nameof(Widget.Id)]));
                return(Mock.Of <IModelBinder>());
            }

            return(null);
        }));

        var factory = new ModelBinderFactory(
            metadataProvider,
            options,
            GetServices());

        var context = new ModelBinderFactoryContext()
        {
            Metadata = metadataProvider.GetMetadataForType(typeof(Widget)),
        };

        // Act
        var result = factory.CreateBinder(context);

        // Assert
        Assert.NotNull(result);
    }
    public TModel Build <TModel>(IStandardTemplate <TModel> template, params object[] parameters)
    {
        var model = Activator.CreateInstance <TModel>();

        var modelBinder = ModelBinderFactory.CreateBinderFor(model);

        return(modelBinder.ApplyParameters(template, parameters));
    }
Esempio n. 5
0
    public void CreateBinder_Caches_NonRootNodes_UsesModelMetadataAsToken()
    {
        // Arrange
        var metadataProvider = new TestModelMetadataProvider();

        var options = Options.Create(new MvcOptions());

        IModelBinder inner = null;

        var widgetProvider = new TestModelBinderProvider(c =>
        {
            if (c.Metadata.ModelType == typeof(Widget))
            {
                inner = c.CreateBinder(c.Metadata.Properties[nameof(Widget.Id)]);
                return(Mock.Of <IModelBinder>());
            }

            return(null);
        });

        var widgetIdProvider = new TestModelBinderProvider(c =>
        {
            Assert.Equal(typeof(WidgetId), c.Metadata.ModelType);
            return(Mock.Of <IModelBinder>());
        });

        options.Value.ModelBinderProviders.Add(widgetProvider);
        options.Value.ModelBinderProviders.Add(widgetIdProvider);

        var factory = new ModelBinderFactory(
            metadataProvider,
            options,
            GetServices());

        var context = new ModelBinderFactoryContext()
        {
            Metadata   = metadataProvider.GetMetadataForType(typeof(Widget)),
            CacheToken = null,
        };

        // Act 1
        var result1 = factory.CreateBinder(context);

        context.Metadata   = context.Metadata.Properties[nameof(Widget.Id)];
        context.CacheToken = context.Metadata;

        // Act 2
        var result2 = factory.CreateBinder(context);

        // Assert
        Assert.Same(inner, result2);
        Assert.Equal(1, widgetProvider.SuccessCount);
        Assert.Equal(1, widgetIdProvider.SuccessCount);
    }
Esempio n. 6
0
        public ConsumerInvokerFactoryTest()
        {
            var services = new ServiceCollection();

            services.AddLogging();
            var provider   = services.BuildServiceProvider();
            var logFactory = provider.GetRequiredService <ILoggerFactory>();
            var binder     = new ModelBinderFactory();

            consumerInvokerFactory = new ConsumerInvokerFactory(logFactory, binder, provider);
        }
Esempio n. 7
0
        private DefaultModelBinderProviderContext(
            DefaultModelBinderProviderContext parent,
            ModelMetadata metadata,
            BindingInfo bindingInfo)
        {
            Metadata = metadata;

            _factory         = parent._factory;
            MetadataProvider = parent.MetadataProvider;
            Visited          = parent.Visited;
            BindingInfo      = bindingInfo;
        }
Esempio n. 8
0
    public void CreateBinder_PassesExpectedBindingInfo(
        BindingInfo parameterBindingInfo,
        BindingMetadata bindingMetadata,
        BindingInfo expectedInfo)
    {
        // Arrange
        var metadataProvider = new TestModelMetadataProvider();

        metadataProvider.ForType <Employee>().BindingDetails(binding =>
        {
            binding.BinderModelName = bindingMetadata.BinderModelName;
            binding.BinderType      = bindingMetadata.BinderType;
            binding.BindingSource   = bindingMetadata.BindingSource;
            if (bindingMetadata.PropertyFilterProvider != null)
            {
                binding.PropertyFilterProvider = bindingMetadata.PropertyFilterProvider;
            }
        });

        var modelBinder         = Mock.Of <IModelBinder>();
        var modelBinderProvider = new TestModelBinderProvider(context =>
        {
            Assert.Equal(typeof(Employee), context.Metadata.ModelType);

            Assert.NotNull(context.BindingInfo);
            Assert.Equal(expectedInfo.BinderModelName, context.BindingInfo.BinderModelName, StringComparer.Ordinal);
            Assert.Equal(expectedInfo.BinderType, context.BindingInfo.BinderType);
            Assert.Equal(expectedInfo.BindingSource, context.BindingInfo.BindingSource);
            Assert.Same(expectedInfo.PropertyFilterProvider, context.BindingInfo.PropertyFilterProvider);

            return(modelBinder);
        });

        var options = Options.Create(new MvcOptions());

        options.Value.ModelBinderProviders.Insert(0, modelBinderProvider);

        var factory = new ModelBinderFactory(
            metadataProvider,
            options,
            GetServices());
        var factoryContext = new ModelBinderFactoryContext
        {
            BindingInfo = parameterBindingInfo,
            Metadata    = metadataProvider.GetMetadataForType(typeof(Employee)),
        };

        // Act & Assert
        var result = factory.CreateBinder(factoryContext);

        // Confirm our IModelBinderProvider was called.
        Assert.Same(modelBinder, result);
    }
        public IModelBinder?GetBinder(ModelBinderProviderContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var modelType = context.Metadata.ModelType;

            if (null == modelType)
            {
                // Returning null means go and try other IModelBinderProvider
                // Model type should be preset
                return(null);
            }

            var modelAttributes = modelType.GetCustomAttributes(inherit: false);

            var discriminator = Fn.FindDiscriminator(modelAttributes);
            var cases         = Fn.FilterDiscriminatorCases(modelAttributes).ToList();

            if (null == discriminator)
            {
                // If discriminator attribute not preset, then we do nothing
                return(null);
            }

            if (!cases.Any())
            {
                throw new NoDiscriminatorCasesProvidedException(modelType);
            }

            var reader = CreateDiscriminatorReader(_mvcOptions, context.MetadataProvider, context.BindingInfo.BindingSource);

            if (null == reader)
            {
                return(null);
            }

            var factory = new ModelBinderFactory(context.MetadataProvider, _mvcOptions, context.Services);

            return(new DiscriminatorModelBinder(factory, context.MetadataProvider, discriminator, cases, reader));
        }
Esempio n. 10
0
    public void CreateBinder_Throws_WhenNoProviders()
    {
        // Arrange
        var expected = $"'{typeof(MvcOptions).FullName}.{nameof(MvcOptions.ModelBinderProviders)}' must not be " +
                       $"empty. At least one '{typeof(IModelBinderProvider).FullName}' is required to model bind.";
        var metadataProvider = new TestModelMetadataProvider();
        var options          = Options.Create(new MvcOptions());
        var factory          = new ModelBinderFactory(
            metadataProvider,
            options,
            GetServices());
        var context = new ModelBinderFactoryContext()
        {
            Metadata = metadataProvider.GetMetadataForType(typeof(string)),
        };

        // Act & Assert
        var exception = Assert.Throws <InvalidOperationException>(() => factory.CreateBinder(context));

        Assert.Equal(expected, exception.Message);
    }
Esempio n. 11
0
    public void CreateBinder_CreatesNoOpBinder_WhenPropertyBindingIsNotAllowed()
    {
        // Arrange
        var metadataProvider = new TestModelMetadataProvider();

        metadataProvider
        .ForProperty <Widget>(nameof(Widget.Id))
        .BindingDetails(m => m.IsBindingAllowed = false);

        var modelBinder = new ByteArrayModelBinder(NullLoggerFactory.Instance);

        var options = Options.Create(new MvcOptions());

        options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c =>
        {
            if (c.Metadata.ModelType == typeof(WidgetId))
            {
                return(modelBinder);
            }

            return(null);
        }));

        var factory = new ModelBinderFactory(
            metadataProvider,
            options,
            GetServices());

        var context = new ModelBinderFactoryContext()
        {
            Metadata = metadataProvider.GetMetadataForProperty(typeof(Widget), nameof(Widget.Id)),
        };

        // Act
        var result = factory.CreateBinder(context);

        // Assert
        Assert.NotNull(result);
        Assert.IsType <NoOpBinder>(result);
    }
Esempio n. 12
0
    public void CreateBinder_BreaksCycles()
    {
        // Arrange
        var metadataProvider = new TestModelMetadataProvider();

        var callCount = 0;

        var options = Options.Create(new MvcOptions());

        options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c =>
        {
            var currentCallCount = ++callCount;
            Assert.Equal(typeof(Employee), c.Metadata.ModelType);
            var binder = c.CreateBinder(c.Metadata.Properties[nameof(Employee.Manager)]);

            if (currentCallCount == 2)
            {
                Assert.IsType <PlaceholderBinder>(binder);
            }

            return(Mock.Of <IModelBinder>());
        }));

        var factory = new ModelBinderFactory(
            metadataProvider,
            options,
            GetServices());

        var context = new ModelBinderFactoryContext()
        {
            Metadata = metadataProvider.GetMetadataForType(typeof(Employee)),
        };

        // Act
        var result = factory.CreateBinder(context);

        // Assert
        Assert.NotNull(result);
    }
Esempio n. 13
0
        public DefaultModelBinderProviderContext(
            ModelBinderFactory factory,
            ModelBinderFactoryContext factoryContext)
        {
            _factory = factory;
            Metadata = factoryContext.Metadata;
            BindingInfo bindingInfo;

            if (factoryContext.BindingInfo != null)
            {
                bindingInfo = new BindingInfo(factoryContext.BindingInfo);
            }
            else
            {
                bindingInfo = new BindingInfo();
            }

            bindingInfo.TryApplyBindingInfo(Metadata);
            BindingInfo = bindingInfo;

            MetadataProvider = _factory._metadataProvider;
            Visited          = new Dictionary <Key, IModelBinder?>();
        }
Esempio n. 14
0
    public void CreateBinder_Throws_WhenBinderNotCreated()
    {
        // Arrange
        var metadataProvider = new TestModelMetadataProvider();
        var options          = Options.Create(new MvcOptions());

        options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(_ => null));

        var factory = new ModelBinderFactory(
            metadataProvider,
            options,
            GetServices());
        var context = new ModelBinderFactoryContext()
        {
            Metadata = metadataProvider.GetMetadataForType(typeof(string)),
        };

        // Act & Assert
        var exception = Assert.Throws <InvalidOperationException>(() => factory.CreateBinder(context));

        Assert.Equal(
            $"Could not create a model binder for model object of type '{typeof(string).FullName}'.",
            exception.Message);
    }
Esempio n. 15
0
        public void CreateBinder_BreaksCycles()
        {
            // Arrange
            var metadataProvider = new TestModelMetadataProvider();

            var callCount = 0;

            var options = new TestOptionsManager<MvcOptions>();
            options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c =>
            {
                var currentCallCount = ++callCount;
                Assert.Equal(typeof(Employee), c.Metadata.ModelType);
                var binder = c.CreateBinder(c.Metadata.Properties[nameof(Employee.Manager)]);

                if (currentCallCount == 2)
                {
                    Assert.IsType<PlaceholderBinder>(binder);
                }

                return Mock.Of<IModelBinder>();
            }));

            var factory = new ModelBinderFactory(metadataProvider, options);

            var context = new ModelBinderFactoryContext()
            {
                Metadata = metadataProvider.GetMetadataForType(typeof(Employee)),
            };

            // Act
            var result = factory.CreateBinder(context);

            // Assert
            Assert.NotNull(result);
        }
Esempio n. 16
0
        public void CreateBinder_Caches_NonRootNodes_UsesModelMetadataAsToken()
        {
            // Arrange
            var metadataProvider = new TestModelMetadataProvider();

            var options = new TestOptionsManager<MvcOptions>();

            IModelBinder inner = null;

            var widgetProvider = new TestModelBinderProvider(c =>
            {
                if (c.Metadata.ModelType == typeof(Widget))
                {
                    inner = c.CreateBinder(c.Metadata.Properties[nameof(Widget.Id)]);
                    return Mock.Of<IModelBinder>();
                }

                return null;
            });

            var widgetIdProvider = new TestModelBinderProvider(c =>
            {
                Assert.Equal(typeof(WidgetId), c.Metadata.ModelType);
                return Mock.Of<IModelBinder>();
            });

            options.Value.ModelBinderProviders.Add(widgetProvider);
            options.Value.ModelBinderProviders.Add(widgetIdProvider);

            var factory = new ModelBinderFactory(metadataProvider, options);

            var context = new ModelBinderFactoryContext()
            {
                Metadata = metadataProvider.GetMetadataForType(typeof(Widget)),
                CacheToken = null,
            };

            // Act 1
            var result1 = factory.CreateBinder(context);

            context.Metadata = context.Metadata.Properties[nameof(Widget.Id)];
            context.CacheToken = context.Metadata;

            // Act 2
            var result2 = factory.CreateBinder(context);

            // Assert
            Assert.Same(inner, result2);
            Assert.Equal(1, widgetProvider.SuccessCount);
            Assert.Equal(1, widgetIdProvider.SuccessCount);
        }
Esempio n. 17
0
        public void CreateBinder_Caches_NonRootNodes_WhenNonRootNodeReturnsNull()
        {
            // Arrange
            var metadataProvider = new TestModelMetadataProvider();

            var options = new TestOptionsManager<MvcOptions>();

            IModelBinder inner = null;

            var widgetProvider = new TestModelBinderProvider(c =>
            {
                if (c.Metadata.ModelType == typeof(Widget))
                {
                    var binder = c.CreateBinder(c.Metadata.Properties[nameof(Widget.Id)]);
                    Assert.IsType<NoOpBinder>(binder);
                    if (inner == null)
                    {
                        inner = binder;
                    }
                    else
                    {
                        Assert.Same(inner, binder);
                    }

                    return Mock.Of<IModelBinder>();
                }

                return null;
            });

            var widgetIdProvider = new TestModelBinderProvider(c =>
            {
                Assert.Equal(typeof(WidgetId), c.Metadata.ModelType);
                return null;
            });

            options.Value.ModelBinderProviders.Add(widgetProvider);
            options.Value.ModelBinderProviders.Add(widgetIdProvider);

            var factory = new ModelBinderFactory(metadataProvider, options);

            var context = new ModelBinderFactoryContext()
            {
                Metadata = metadataProvider.GetMetadataForType(typeof(Widget)),
                CacheToken = null, // We want the outermost provider to run twice.
            };

            // Act
            var result1 = factory.CreateBinder(context);
            var result2 = factory.CreateBinder(context);

            // Assert
            Assert.NotSame(result1, result2);

            Assert.Equal(2, widgetProvider.SuccessCount);
            Assert.Equal(0, widgetIdProvider.SuccessCount);
        }
Esempio n. 18
0
        public void CreateBinder_CreatesNoOpBinder_WhenPropertyBindingIsNotAllowed()
        {
            // Arrange
            var metadataProvider = new TestModelMetadataProvider();
            metadataProvider
                .ForProperty<Widget>(nameof(Widget.Id))
                .BindingDetails(m => m.IsBindingAllowed = false);

            var modelBinder = new ByteArrayModelBinder();

            var options = new TestOptionsManager<MvcOptions>();
            options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c =>
            {
                if (c.Metadata.ModelType == typeof(WidgetId))
                {
                    return modelBinder;
                }

                return null;
            }));

            var factory = new ModelBinderFactory(metadataProvider, options);

            var context = new ModelBinderFactoryContext()
            {
                Metadata = metadataProvider.GetMetadataForProperty(typeof(Widget), nameof(Widget.Id)),
            };

            // Act
            var result = factory.CreateBinder(context);

            // Assert
            Assert.NotNull(result);
            Assert.IsType<NoOpBinder>(result);
        }
Esempio n. 19
0
        public void CreateBinder_CreatesNoOpBinder_WhenPropertyDoesntHaveABinder()
        {
            // Arrange
            var metadataProvider = new TestModelMetadataProvider();

            // There isn't a provider that can handle WidgetId.
            var options = new TestOptionsManager<MvcOptions>();
            options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c =>
            {
                if (c.Metadata.ModelType == typeof(Widget))
                {
                    Assert.NotNull(c.CreateBinder(c.Metadata.Properties[nameof(Widget.Id)]));
                    return Mock.Of<IModelBinder>();
                }

                return null;
            }));

            var factory = new ModelBinderFactory(metadataProvider, options);

            var context = new ModelBinderFactoryContext()
            {
                Metadata = metadataProvider.GetMetadataForType(typeof(Widget)),
            };

            // Act
            var result = factory.CreateBinder(context);

            // Assert
            Assert.NotNull(result);
        }
Esempio n. 20
0
        public void CreateBinder_Throws_WhenBinderNotCreated()
        {
            // Arrange
            var metadataProvider = new TestModelMetadataProvider();
            var options = new TestOptionsManager<MvcOptions>();
            var factory = new ModelBinderFactory(metadataProvider, options);

            var context = new ModelBinderFactoryContext()
            {
                Metadata = metadataProvider.GetMetadataForType(typeof(string)),
            };

            // Act
            var exception = Assert.Throws<InvalidOperationException>(() => factory.CreateBinder(context));

            // Assert
            Assert.Equal(
                $"Could not create a model binder for model object of type '{typeof(string).FullName}'.",
                exception.Message);
        }
Esempio n. 21
0
        public void CreateBinder_PassesExpectedBindingInfo(
            BindingInfo parameterBindingInfo,
            BindingMetadata bindingMetadata,
            BindingInfo expectedInfo)
        {
            // Arrange
            var metadataProvider = new TestModelMetadataProvider();
            metadataProvider.ForType<Employee>().BindingDetails(binding =>
            {
                binding.BinderModelName = bindingMetadata.BinderModelName;
                binding.BinderType = bindingMetadata.BinderType;
                binding.BindingSource = bindingMetadata.BindingSource;
                if (bindingMetadata.PropertyFilterProvider != null)
                {
                    binding.PropertyFilterProvider = bindingMetadata.PropertyFilterProvider;
                }
            });

            var modelBinder = Mock.Of<IModelBinder>();
            var modelBinderProvider = new TestModelBinderProvider(context =>
            {
                Assert.Equal(typeof(Employee), context.Metadata.ModelType);

                Assert.NotNull(context.BindingInfo);
                Assert.Equal(expectedInfo.BinderModelName, context.BindingInfo.BinderModelName, StringComparer.Ordinal);
                Assert.Equal(expectedInfo.BinderType, context.BindingInfo.BinderType);
                Assert.Equal(expectedInfo.BindingSource, context.BindingInfo.BindingSource);
                Assert.Same(expectedInfo.PropertyFilterProvider, context.BindingInfo.PropertyFilterProvider);

                return modelBinder;
            });

            var options = new TestOptionsManager<MvcOptions>();
            options.Value.ModelBinderProviders.Insert(0, modelBinderProvider);

            var factory = new ModelBinderFactory(metadataProvider, options);
            var factoryContext = new ModelBinderFactoryContext
            {
                BindingInfo = parameterBindingInfo,
                Metadata = metadataProvider.GetMetadataForType(typeof(Employee)),
            };

            // Act & Assert
            var result = factory.CreateBinder(factoryContext);

            // Confirm our IModelBinderProvider was called.
            Assert.Same(modelBinder, result);
        }
Esempio n. 22
0
        public void CreateBinder_NestedProperties()
        {
            // Arrange
            var metadataProvider = new TestModelMetadataProvider();

            var options = new TestOptionsManager<MvcOptions>();
            options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c =>
            {
                if (c.Metadata.ModelType == typeof(Widget))
                {
                    Assert.NotNull(c.CreateBinder(c.Metadata.Properties[nameof(Widget.Id)]));
                    return Mock.Of<IModelBinder>();
                }
                else if (c.Metadata.ModelType == typeof(WidgetId))
                {
                    return Mock.Of<IModelBinder>();
                }

                return null;
            }));

            var factory = new ModelBinderFactory(metadataProvider, options);

            var context = new ModelBinderFactoryContext()
            {
                Metadata = metadataProvider.GetMetadataForType(typeof(Widget)),
            };

            // Act
            var result = factory.CreateBinder(context);

            // Assert
            Assert.NotNull(result);
        }
Esempio n. 23
0
        public void CreateBinder_DoesNotCache_WhenTokenIsNull()
        {
            // Arrange
            var metadataProvider = new TestModelMetadataProvider();

            var options = new TestOptionsManager<MvcOptions>();
            options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c =>
            {
                Assert.Equal(typeof(Employee), c.Metadata.ModelType);
                return Mock.Of<IModelBinder>();
            }));

            var factory = new ModelBinderFactory(metadataProvider, options);

            var context = new ModelBinderFactoryContext()
            {
                Metadata = metadataProvider.GetMetadataForType(typeof(Employee)),
            };

            // Act
            var result1 = factory.CreateBinder(context);
            var result2 = factory.CreateBinder(context);

            // Assert
            Assert.NotSame(result1, result2);
        }