コード例 #1
0
ファイル: PageBinderFactoryTest.cs プロジェクト: yelau/Mvc
        public async Task ModelBinderFactory_BindsPropertiesOnPageModel()
        {
            // Arrange
            var type = typeof(PageModelWithProperty).GetTypeInfo();

            var actionDescriptor = new CompiledPageActionDescriptor
            {
                BoundProperties = new[]
                {
                    new PageBoundPropertyDescriptor()
                    {
                        Name          = nameof(PageModelWithProperty.Id),
                        ParameterType = typeof(int),
                        Property      = type.GetProperty(nameof(PageModelWithProperty.Id)),
                    },
                    new PageBoundPropertyDescriptor()
                    {
                        Name          = nameof(PageModelWithProperty.RouteDifferentValue),
                        ParameterType = typeof(string),
                        Property      = type.GetProperty(nameof(PageModelWithProperty.RouteDifferentValue)),
                    },
                    new PageBoundPropertyDescriptor()
                    {
                        Name          = nameof(PageModelWithProperty.PropertyWithNoValue),
                        ParameterType = typeof(string),
                        Property      = type.GetProperty(nameof(PageModelWithProperty.PropertyWithNoValue)),
                    }
                },

                HandlerTypeInfo = typeof(PageModelWithProperty).GetTypeInfo(),
                PageTypeInfo    = typeof(PageWithProperty).GetTypeInfo(),
                ModelTypeInfo   = typeof(PageModelWithProperty).GetTypeInfo(),
            };

            var binder = new TestParameterBinder(new Dictionary <string, object>
            {
                { nameof(PageModelWithProperty.Id), 10 },
                { nameof(PageModelWithProperty.RouteDifferentValue), "route-value" }
            });

            var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var modelBinderFactory    = TestModelBinderFactory.CreateDefault();

            var factory = PageBinderFactory.CreatePropertyBinder(binder, modelMetadataProvider, modelBinderFactory, actionDescriptor);

            var page = new PageWithProperty
            {
                PageContext = GetPageContext()
            };

            var model = new PageModelWithProperty();

            // Act
            await factory(page.PageContext, model);

            // Assert
            // Verify that the page properties were not bound.
            Assert.Equal(default, page.Id);
コード例 #2
0
        public async Task CreatePropertyBinder_ValidatesTopLevelProperties()
        {
            // Arrange
            var type = typeof(PageModelWithValidation).GetTypeInfo();

            var actionDescriptor = new CompiledPageActionDescriptor
            {
                BoundProperties = new[]
                {
                    new PageBoundPropertyDescriptor()
                    {
                        Name          = nameof(PageModelWithValidation.Validated),
                        ParameterType = typeof(string),
                        Property      = type.GetProperty(nameof(PageModelWithValidation.Validated)),
                    },
                },

                HandlerTypeInfo = type,
                PageTypeInfo    = typeof(PageWithProperty).GetTypeInfo(),
                ModelTypeInfo   = type,
            };

            var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var modelBinderFactory    = TestModelBinderFactory.CreateDefault();

            var binder = new ParameterBinder(
                modelMetadataProvider,
                modelBinderFactory,
                new DefaultObjectValidator(
                    modelMetadataProvider,
                    new[] { TestModelValidatorProvider.CreateDefaultProvider() }),
                NullLoggerFactory.Instance);

            var factory = PageBinderFactory.CreatePropertyBinder(binder, modelMetadataProvider, modelBinderFactory, actionDescriptor);

            var page = new PageWithProperty
            {
                PageContext = GetPageContext()
            };

            var model = new PageModelWithValidation();

            // Act
            await factory(page.PageContext, model);

            // Assert
            var modelState = page.PageContext.ModelState;

            Assert.False(modelState.IsValid);
            Assert.Collection(
                modelState,
                kvp =>
            {
                Assert.Equal(nameof(PageModelWithValidation.Validated), kvp.Key);
            });
        }
コード例 #3
0
        public async Task CreateHandlerBinder_ValidatesTopLevelParameters()
        {
            // Arrange
            var type             = typeof(PageModelWithExecutors);
            var actionDescriptor = GetActionDescriptorWithHandlerMethod(type, nameof(PageModelWithExecutors.OnPostWithValidation));

            // Act

            var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var modelBinderFactory    = TestModelBinderFactory.CreateDefault();

            var parameterBinder = new ParameterBinder(
                modelMetadataProvider,
                modelBinderFactory,
                new DefaultObjectValidator(
                    modelMetadataProvider,
                    new[] { TestModelValidatorProvider.CreateDefaultProvider() }),
                NullLoggerFactory.Instance);

            var factory = PageBinderFactory.CreateHandlerBinder(
                parameterBinder,
                modelMetadataProvider,
                modelBinderFactory,
                actionDescriptor,
                actionDescriptor.HandlerMethods[0]);

            var page = new PageWithProperty
            {
                PageContext = GetPageContext()
            };

            var model     = new PageModelWithExecutors();
            var arguments = new Dictionary <string, object>();

            // Act
            await factory(page.PageContext, arguments);

            // Assert
            var modelState = page.PageContext.ModelState;

            Assert.False(modelState.IsValid);
            Assert.Collection(
                page.PageContext.ModelState,
                kvp =>
            {
                Assert.Equal("name", kvp.Key);
            });
        }
コード例 #4
0
        public async Task CreatePropertyBinder_SkipsBindingPropertiesWithBindNever()
        {
            // Arrange
            var type = typeof(PageModelWithBindNeverProperty).GetTypeInfo();

            var actionDescriptor = new CompiledPageActionDescriptor
            {
                BoundProperties = new[]
                {
                    new PageBoundPropertyDescriptor()
                    {
                        Name          = nameof(PageModelWithBindNeverProperty.BindNeverProperty),
                        ParameterType = typeof(string),
                        Property      = type.GetProperty(nameof(PageModelWithBindNeverProperty.BindNeverProperty)),
                    },
                },

                HandlerTypeInfo = type,
                PageTypeInfo    = typeof(PageWithProperty).GetTypeInfo(),
                ModelTypeInfo   = type,
            };

            var binder = new TestParameterBinder(new Dictionary <string, object>
            {
                { nameof(PageModelWithBindNeverProperty.BindNeverProperty), "value" },
            });

            var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var modelBinderFactory    = TestModelBinderFactory.CreateDefault();

            var factory = PageBinderFactory.CreatePropertyBinder(binder, modelMetadataProvider, modelBinderFactory, actionDescriptor);

            var page = new PageWithProperty
            {
                PageContext = GetPageContext()
            };

            var model = new PageModelWithBindNeverProperty();

            // Act
            await factory(page.PageContext, model);

            // Assert
            Assert.Null(model.BindNeverProperty);
        }
コード例 #5
0
        public async Task ModelBinderFactory_PreservesExistingValueIfModelBindingFailed()
        {
            // Arrange
            var type = typeof(PageModelWithDefaultValue).GetTypeInfo();

            var actionDescriptor = new CompiledPageActionDescriptor
            {
                BoundProperties = new[]
                {
                    new PageBoundPropertyDescriptor()
                    {
                        Name          = nameof(PageModelWithDefaultValue.PropertyWithDefaultValue),
                        ParameterType = typeof(string),
                        Property      = type.GetProperty(nameof(PageModelWithDefaultValue.PropertyWithDefaultValue)),
                    },
                },

                HandlerTypeInfo = type,
                PageTypeInfo    = typeof(PageWithProperty).GetTypeInfo(),
                ModelTypeInfo   = type,
            };

            var binder = new TestParameterBinder(new Dictionary <string, object>());

            var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var modelBinderFactory    = TestModelBinderFactory.CreateDefault();

            var factory = PageBinderFactory.CreatePropertyBinder(binder, modelMetadataProvider, modelBinderFactory, actionDescriptor);

            var page = new PageWithProperty
            {
                PageContext = GetPageContext()
            };

            var model        = new PageModelWithDefaultValue();
            var defaultValue = model.PropertyWithDefaultValue;

            // Act
            await factory(page.PageContext, model);

            // Assert
            Assert.Equal(defaultValue, model.PropertyWithDefaultValue);
        }
コード例 #6
0
        private PageActionInvokerCacheEntry CreateCacheEntry(
            ActionInvokerProviderContext context,
            FilterItem[] cachedFilters)
        {
            var compiledActionDescriptor = (CompiledPageActionDescriptor)context.ActionContext.ActionDescriptor;

            var viewDataFactory = ViewDataDictionaryFactory.CreateFactory(compiledActionDescriptor.DeclaredModelTypeInfo);

            var pageFactory    = _pageFactoryProvider.CreatePageFactory(compiledActionDescriptor);
            var pageDisposer   = _pageFactoryProvider.CreatePageDisposer(compiledActionDescriptor);
            var propertyBinder = PageBinderFactory.CreatePropertyBinder(
                _parameterBinder,
                _modelMetadataProvider,
                _modelBinderFactory,
                compiledActionDescriptor);

            Func <PageContext, object>   modelFactory  = null;
            Action <PageContext, object> modelReleaser = null;

            if (compiledActionDescriptor.ModelTypeInfo != compiledActionDescriptor.PageTypeInfo)
            {
                modelFactory  = _modelFactoryProvider.CreateModelFactory(compiledActionDescriptor);
                modelReleaser = _modelFactoryProvider.CreateModelDisposer(compiledActionDescriptor);
            }

            var viewStartFactories = GetViewStartFactories(compiledActionDescriptor);

            var handlerExecutors = GetHandlerExecutors(compiledActionDescriptor);
            var handlerBinders   = GetHandlerBinders(compiledActionDescriptor);

            return(new PageActionInvokerCacheEntry(
                       compiledActionDescriptor,
                       viewDataFactory,
                       pageFactory,
                       pageDisposer,
                       modelFactory,
                       modelReleaser,
                       propertyBinder,
                       handlerExecutors,
                       handlerBinders,
                       viewStartFactories,
                       cachedFilters));
        }
コード例 #7
0
        public async Task CreateHandlerBinder_BindsHandlerParameters()
        {
            // Arrange
            var type             = typeof(PageModelWithExecutors);
            var actionDescriptor = GetActionDescriptorWithHandlerMethod(type, nameof(PageModelWithExecutors.OnGet));

            // Act
            var parameterBinder = new TestParameterBinder(new Dictionary <string, object>()
            {
                { "id", "value" },
            });

            var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var modelBinderFactory    = TestModelBinderFactory.CreateDefault();

            var factory = PageBinderFactory.CreateHandlerBinder(
                parameterBinder,
                modelMetadataProvider,
                modelBinderFactory,
                actionDescriptor,
                actionDescriptor.HandlerMethods[0]);

            var page = new PageWithProperty
            {
                PageContext = GetPageContext()
            };

            var model     = new PageModelWithExecutors();
            var arguments = new Dictionary <string, object>();

            // Act
            await factory(page.PageContext, arguments);

            // Assert
            Assert.Collection(
                arguments,
                kvp =>
            {
                Assert.Equal("id", kvp.Key);
                Assert.Equal("value", kvp.Value);
            });
        }
コード例 #8
0
        private PageHandlerBinderDelegate[] GetHandlerBinders(CompiledPageActionDescriptor actionDescriptor)
        {
            if (actionDescriptor.HandlerMethods == null || actionDescriptor.HandlerMethods.Count == 0)
            {
                return(Array.Empty <PageHandlerBinderDelegate>());
            }

            var results = new PageHandlerBinderDelegate[actionDescriptor.HandlerMethods.Count];

            for (var i = 0; i < actionDescriptor.HandlerMethods.Count; i++)
            {
                results[i] = PageBinderFactory.CreateHandlerBinder(
                    _parameterBinder,
                    _modelMetadataProvider,
                    _modelBinderFactory,
                    actionDescriptor,
                    actionDescriptor.HandlerMethods[i]);
            }

            return(results);
        }
コード例 #9
0
        public void GetModelBinderFactory_ReturnsNullIfPageHasNoVisibleBoundProperties()
        {
            // Arrange
            var actionDescriptor = new CompiledPageActionDescriptor
            {
                PageTypeInfo = typeof(PageWithNoVisibleBoundProperties).GetTypeInfo(),
            };
            var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var modelBinderFactory    = TestModelBinderFactory.CreateDefault();

            var binder = new ParameterBinder(
                modelMetadataProvider,
                modelBinderFactory,
                Mock.Of <IModelValidatorProvider>(),
                NullLoggerFactory.Instance);

            // Act
            var factory = PageBinderFactory.CreatePropertyBinder(binder, modelMetadataProvider, modelBinderFactory, actionDescriptor);

            // Assert
            Assert.Same(PageBinderFactory.NullPropertyBinder, factory);
        }
コード例 #10
0
        public async Task CreateHandlerBinder_SkipBindingParametersThatDisallowBinding()
        {
            // Arrange
            var type             = typeof(PageModelWithExecutors);
            var actionDescriptor = GetActionDescriptorWithHandlerMethod(type, nameof(PageModelWithExecutors.OnGetWithBindNever));

            // Act
            var parameterBinder = new TestParameterBinder(new Dictionary <string, object>()
            {
                { "id", "value" },
            });

            var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var modelBinderFactory    = TestModelBinderFactory.CreateDefault();

            var factory = PageBinderFactory.CreateHandlerBinder(
                parameterBinder,
                modelMetadataProvider,
                modelBinderFactory,
                actionDescriptor,
                actionDescriptor.HandlerMethods[0]);

            var page = new PageWithProperty
            {
                PageContext = GetPageContext()
            };

            var model     = new PageModelWithExecutors();
            var arguments = new Dictionary <string, object>();

            // Act
            await factory(page.PageContext, arguments);

            // Assert
            Assert.Empty(arguments);
        }
コード例 #11
0
        public async Task ModelBinderFactory_BindsPropertyWithoutSupportsGet_WhenRequestIsNotGet()
        {
            // Arrange
            var type = typeof(PageModelWithSupportsGetProperty).GetTypeInfo();

            var actionDescriptor = new CompiledPageActionDescriptor
            {
                BoundProperties = new[]
                {
                    new PageBoundPropertyDescriptor()
                    {
                        Name          = nameof(PageModelWithSupportsGetProperty.SupportsGet),
                        ParameterType = typeof(string),
                        Property      = type.GetProperty(nameof(PageModelWithSupportsGetProperty.SupportsGet)),
                        BindingInfo   = new BindingInfo()
                        {
                            RequestPredicate = ((IRequestPredicateProvider) new BindPropertyAttribute()
                            {
                                SupportsGet = true
                            }).RequestPredicate,
                        }
                    },
                    new PageBoundPropertyDescriptor()
                    {
                        Name          = nameof(PageModelWithSupportsGetProperty.Default),
                        ParameterType = typeof(string),
                        Property      = type.GetProperty(nameof(PageModelWithSupportsGetProperty.Default)),
                    },
                },

                HandlerTypeInfo = type,
                PageTypeInfo    = typeof(PageWithProperty).GetTypeInfo(),
                ModelTypeInfo   = type,
            };

            var binder = new TestParameterBinder(new Dictionary <string, object>()
            {
                { "SupportsGet", "value" },
                { "Default", "value" },
            });

            var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var modelBinderFactory    = TestModelBinderFactory.CreateDefault();

            var factory = PageBinderFactory.CreatePropertyBinder(binder, modelMetadataProvider, modelBinderFactory, actionDescriptor);

            var page = new PageWithProperty
            {
                PageContext = GetPageContext()
            };

            page.HttpContext.Request.Method = "Post";

            var model = new PageModelWithSupportsGetProperty();

            // Act
            await factory(page.PageContext, model);

            // Assert
            Assert.Equal("value", model.SupportsGet);
            Assert.Equal("value", model.Default);
        }