コード例 #1
0
    private PageActionInvokerCacheEntry CreateCacheEntry(
        CompiledPageActionDescriptor compiledActionDescriptor,
        FilterItem[] cachedFilters)
    {
        var viewDataFactory = ViewDataDictionaryFactory.CreateFactory(compiledActionDescriptor.DeclaredModelTypeInfo);

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

        Func <PageContext, object>?           modelFactory  = null;
        Func <PageContext, object, ValueTask>?modelReleaser = null;

        if (compiledActionDescriptor.ModelTypeInfo != compiledActionDescriptor.PageTypeInfo)
        {
            modelFactory  = _modelFactoryProvider.CreateModelFactory(compiledActionDescriptor);
            modelReleaser = _modelFactoryProvider.CreateAsyncModelDisposer(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));
    }
コード例 #2
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);
    }
コード例 #3
0
    public void CreateModelDisposer_ReturnsDisposerFromModelActivatorProvider()
    {
        // Arrange
        var descriptor = new CompiledPageActionDescriptor
        {
            ModelTypeInfo = typeof(SimpleModel).GetTypeInfo()
        };
        var pageContext                       = new PageContext();
        var modelActivatorProvider            = new Mock <IPageModelActivatorProvider>();
        Action <PageContext, object> disposer = (_, __) => { };

        modelActivatorProvider.Setup(p => p.CreateReleaser(descriptor))
        .Returns(disposer);
        var factoryProvider = CreateModelFactoryProvider(modelActivatorProvider.Object);

        // Act
        var actual = factoryProvider.CreateModelDisposer(descriptor);

        // Assert
        Assert.Same(disposer, actual);
    }
コード例 #4
0
    /// <inheritdoc />
    public virtual Func <PageContext, object> CreateActivator(CompiledPageActionDescriptor actionDescriptor)
    {
        if (actionDescriptor == null)
        {
            throw new ArgumentNullException(nameof(actionDescriptor));
        }

        var modelTypeInfo = actionDescriptor.ModelTypeInfo?.AsType();

        if (modelTypeInfo == null)
        {
            throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull(
                                            nameof(actionDescriptor.ModelTypeInfo),
                                            nameof(actionDescriptor)),
                                        nameof(actionDescriptor));
        }

        var factory = ActivatorUtilities.CreateFactory(modelTypeInfo, Type.EmptyTypes);

        return((context) => factory(context.HttpContext.RequestServices, Array.Empty <object>()));
    }
コード例 #5
0
        private static AuthorizationFailedHandlerAttribute GetCustomHandlerOrDefault(CompiledPageActionDescriptor compiledPageActionDescriptor)
        {
            AuthorizationFailedHandlerAttribute result;
            HandlerMethodDescriptor             methodDescriptor = compiledPageActionDescriptor.HandlerMethods[0];

            if (methodDescriptor != null)
            {
                result = methodDescriptor.MethodInfo
                         .GetCustomAttributes <AuthorizationFailedHandlerAttribute>(false)
                         .FirstOrDefault();
                if (result != null)
                {
                    return(result);
                }
            }

            result = compiledPageActionDescriptor.ModelTypeInfo
                     .GetCustomAttributes <AuthorizationFailedHandlerAttribute>(true)
                     .FirstOrDefault();
            return(result);
        }
コード例 #6
0
    public void CreateReleaser_CreatesDelegateThatDisposesDisposableTypes()
    {
        // Arrange
        var context = new PageContext();

        var activator        = new DefaultPageModelActivatorProvider();
        var actionDescriptor = new CompiledPageActionDescriptor
        {
            ModelTypeInfo = typeof(DisposableModel).GetTypeInfo(),
        };

        var model = new DisposableModel();

        // Act & Assert
        var releaser = activator.CreateReleaser(actionDescriptor);

        releaser(context, model);

        // Assert
        Assert.True(model.Disposed);
    }
コード例 #7
0
        public void GetModelBinderFactory_ReturnsNullIfPageModelHasNoVisibleBoundProperties()
        {
            // Arrange
            var actionDescriptor = new CompiledPageActionDescriptor
            {
                PageTypeInfo  = typeof(object).GetTypeInfo(),
                ModelTypeInfo = typeof(PageModelWithNoVisibleBoundProperties).GetTypeInfo(),
            };
            var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var binder = new ParameterBinder(
                modelMetadataProvider,
                TestModelBinderFactory.CreateDefault(),
                Mock.Of <IModelValidatorProvider>(),
                NullLoggerFactory.Instance);

            // Act
            var factory = PagePropertyBinderFactory.CreateBinder(binder, modelMetadataProvider, actionDescriptor);

            // Assert
            Assert.Null(factory);
        }
コード例 #8
0
    public void CreateActivator_ReturnsFactoryForPage(Type type)
    {
        // Arrange
        var pageContext = new PageContext();
        var viewContext = new ViewContext();
        var descriptor  = new CompiledPageActionDescriptor
        {
            PageTypeInfo = type.GetTypeInfo(),
        };


        var activator = new DefaultPageActivatorProvider();

        // Act
        var factory  = activator.CreateActivator(descriptor);
        var instance = factory(pageContext, viewContext);

        // Assert
        Assert.NotNull(instance);
        Assert.IsType(type, instance);
    }
コード例 #9
0
    /// <inheritdoc/>
    public Func <PageContext, object> CreateActivator(CompiledPageActionDescriptor descriptor)
    {
        if (descriptor == null)
        {
            throw new ArgumentNullException(nameof(descriptor));
        }

        var modelType = descriptor.ModelTypeInfo?.AsType();

        if (modelType == null)
        {
            throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull(
                                            nameof(descriptor.ModelTypeInfo),
                                            nameof(descriptor)),
                                        nameof(descriptor));
        }

        return(context =>
        {
            return context.HttpContext.RequestServices.GetRequiredService(modelType);
        });
    }
コード例 #10
0
        public void GetModelBinderFactory_ReturnsNullIfPageHasNoSettableBoundProperties()
        {
            // Arrange
            var actionDescriptor = new CompiledPageActionDescriptor
            {
                PageTypeInfo = typeof(PageWithReadOnlyProperties).GetTypeInfo(),
            };
            var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var modelBinderFactory    = TestModelBinderFactory.CreateDefault();

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

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

            // Assert
            Assert.Same(PageBinderFactory.NullPropertyBinder, factory);
        }
コード例 #11
0
        private AuthenticationFailedHandlerAttribute[] GetCustomHandlers(CompiledPageActionDescriptor compiledPageActionDescriptor)
        {
            List <AuthenticationFailedHandlerAttribute> result = new List <AuthenticationFailedHandlerAttribute>();
            HandlerMethodDescriptor methodDescriptor           = compiledPageActionDescriptor.HandlerMethods[0];
            bool checkPageModel = true;

            if (methodDescriptor != null)
            {
                MethodInfo method = methodDescriptor.MethodInfo;
                if (method.HasAttribute <AuthenticationFailedHandlerAttribute>(false))
                {
                    result.AddRange(method.GetCustomAttributes <AuthenticationFailedHandlerAttribute>(false));
                    checkPageModel = false;
                }
            }

            if (checkPageModel)
            {
                Type     baseType;
                TypeInfo controllerType;
                while (true)
                {
                    controllerType = compiledPageActionDescriptor.ModelTypeInfo;
                    if (controllerType.HasAttribute <AuthenticationFailedHandlerAttribute>(false))
                    {
                        result.AddRange(controllerType.GetCustomAttributes <AuthenticationFailedHandlerAttribute>(false));
                        break;
                    }
                    baseType = controllerType.BaseType;
                    if (baseType == null)
                    {
                        break;
                    }

                    controllerType = baseType.GetTypeInfo();
                }
            }
            return(result.ToArray());
        }
コード例 #12
0
    public async Task LoadAsync_CompiledPageActionDescriptor_ReturnsSelf()
    {
        // Arrange
        var mvcOptions      = Options.Create(new MvcOptions());
        var endpointFactory = new ActionEndpointFactory(Mock.Of <RoutePatternTransformer>(), Enumerable.Empty <IRequestDelegateFactory>(), Mock.Of <IServiceProvider>());
        var loader          = new DefaultPageLoader(
            new[] { Mock.Of <IPageApplicationModelProvider>() },
            Mock.Of <IViewCompilerProvider>(),
            endpointFactory,
            RazorPagesOptions,
            mvcOptions);
        var pageDescriptor = new CompiledPageActionDescriptor();

        // Act
        var result1 = await loader.LoadAsync(pageDescriptor, new EndpointMetadataCollection());

        var result2 = await loader.LoadAsync(pageDescriptor, new EndpointMetadataCollection());

        // Assert
        Assert.Same(pageDescriptor, result1);
        Assert.Same(pageDescriptor, result2);
    }
コード例 #13
0
        /// <summary>
        /// Creates a Razor Page model activator.
        /// </summary>
        /// <param name="descriptor">The <see cref="CompiledPageActionDescriptor"/>.</param>
        /// <returns>The delegate used to activate the page model.</returns>
        public Func <PageContext, object> CreateActivator(CompiledPageActionDescriptor descriptor)
        {
            if (descriptor is null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

            if (descriptor.ModelTypeInfo is null)
            {
                throw new ArgumentNullException(
                          nameof(descriptor.ModelTypeInfo) + " property cannot be null.",
                          nameof(descriptor));
            }

            Type pageModelType = descriptor.ModelTypeInfo.AsType();

            InstanceProducer?producer =
                this.pageModelProducers.GetOrAdd(pageModelType, this.GetPageModelProducer);

            if (producer is null)
            {
                throw new InvalidOperationException(
                          string.Format(
                              CultureInfo.InvariantCulture,
                              "For the {0} to function properly, it requires all page models to be registered explicitly " +
                              "in Simple Injector, but a registration for {1} is missing. To ensure all page models are " +
                              "registered properly, call the RegisterPageModels extension method on the Container " +
                              "from within your Startup.Configure method while supplying the IApplicationBuilder " +
                              "instance, e.g. \"this.container.RegisterPageModels(app);\".{2}" +
                              "Full page model name: {3}.",
                              typeof(SimpleInjectorPageModelActivatorProvider).Name,
                              pageModelType.ToFriendlyName(),
                              Environment.NewLine,
                              pageModelType.FullName));
            }

            return(_ => producer.GetInstance());
        }
コード例 #14
0
    public void PageFactorySetsPageContext()
    {
        // Arrange
        var descriptor = new CompiledPageActionDescriptor
        {
            PageTypeInfo = typeof(TestPage).GetTypeInfo(),
        };
        var pageContext = new PageContext
        {
            ActionDescriptor = descriptor
        };
        var viewContext     = new ViewContext();
        var factoryProvider = CreatePageFactory();

        // Act
        var factory  = factoryProvider.CreatePageFactory(descriptor);
        var instance = factory(pageContext, viewContext);

        // Assert
        var testPage = Assert.IsType <TestPage>(instance);

        Assert.Same(pageContext, testPage.PageContext);
    }
コード例 #15
0
 public PageActionInvokerCacheEntry(
     CompiledPageActionDescriptor actionDescriptor,
     Func <IModelMetadataProvider, ModelStateDictionary, ViewDataDictionary> viewDataFactory,
     Func <PageContext, ViewContext, object> pageFactory,
     Action <PageContext, ViewContext, object> releasePage,
     Func <PageContext, object> modelFactory,
     Action <PageContext, object> releaseModel,
     Func <PageContext, object, Task> propertyBinder,
     Func <object, object[], Task <IActionResult> >[] executors,
     IReadOnlyList <Func <IRazorPage> > viewStartFactories,
     FilterItem[] cacheableFilters)
 {
     ActionDescriptor   = actionDescriptor;
     ViewDataFactory    = viewDataFactory;
     PageFactory        = pageFactory;
     ReleasePage        = releasePage;
     ModelFactory       = modelFactory;
     ReleaseModel       = releaseModel;
     PropertyBinder     = propertyBinder;
     Executors          = executors;
     ViewStartFactories = viewStartFactories;
     CacheableFilters   = cacheableFilters;
 }
コード例 #16
0
        public static Func <PageContext, object, Task> CreateBinder(
            ParameterBinder parameterBinder,
            IModelMetadataProvider modelMetadataProvider,
            CompiledPageActionDescriptor actionDescriptor)
        {
            if (parameterBinder == null)
            {
                throw new ArgumentNullException(nameof(parameterBinder));
            }

            if (actionDescriptor == null)
            {
                throw new ArgumentNullException(nameof(actionDescriptor));
            }

            var properties = actionDescriptor.BoundProperties;

            if (properties == null || properties.Count == 0)
            {
                return(null);
            }

            var type     = actionDescriptor.HandlerTypeInfo.AsType();
            var metadata = new ModelMetadata[properties.Count];

            for (var i = 0; i < properties.Count; i++)
            {
                metadata[i] = modelMetadataProvider.GetMetadataForProperty(type, properties[i].Name);
            }

            return(Bind);

            Task Bind(PageContext pageContext, object instance)
            {
                return(BindPropertiesAsync(parameterBinder, pageContext, instance, properties, metadata));
            }
        }
コード例 #17
0
        public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
        {
            IEnumerable <Attribute> attributes = context.ActionDescriptor switch {
                CompiledPageActionDescriptor p => p.ModelTypeInfo.GetCustomAttributes(),
                ControllerActionDescriptor c => c.ControllerTypeInfo.GetCustomAttributes(),
                                    _ => throw new NotImplementedException(
                          $"Unknown controller type: {context.ActionDescriptor.GetType().Name}"
                          )
            };

            ISet <SanityCheckKind> failures = this._checker.Run(SanityCheckKind.MainPasswordIsSet);

            if (failures.Count > 0 && attributes.All(a => a.GetType() != typeof(Ignore)))
            {
                this._nb.Add($"Sanity checks failed: {String.Join(", ", failures)}.");

                context.Result = new RedirectResult(Urls.InitUrl);
            }
            else
            {
                await next();
            }
        }
    }
コード例 #18
0
        public void GetViewStartFactories_FindsFullHeirarchy()
        {
            // Arrange
            var descriptor = new PageActionDescriptor()
            {
                RelativePath      = "/Pages/Level1/Level2/Index.cshtml",
                FilterDescriptors = new FilterDescriptor[0],
                ViewEnginePath    = "/Pages/Level1/Level2/Index.cshtml"
            };

            var compiledPageDescriptor = new CompiledPageActionDescriptor(descriptor)
            {
                PageTypeInfo = typeof(object).GetTypeInfo(),
            };

            var loader = new Mock <IPageLoader>();

            loader
            .Setup(l => l.Load(It.IsAny <PageActionDescriptor>()))
            .Returns(compiledPageDescriptor);

            var fileProvider = new TestFileProvider();

            fileProvider.AddFile("/_ViewStart.cshtml", "page content");
            fileProvider.AddFile("/Pages/_ViewStart.cshtml", "page content");
            fileProvider.AddFile("/Pages/Level1/_ViewStart.cshtml", "page content");
            fileProvider.AddFile("/Pages/Level1/Level2/_ViewStart.cshtml", "page content");
            fileProvider.AddFile("/Pages/Level1/Level3/_ViewStart.cshtml", "page content");

            var razorProject = new TestRazorProject(fileProvider, _hostingEnvironment);

            var mock = new Mock <IRazorPageFactoryProvider>(MockBehavior.Strict);

            mock
            .Setup(p => p.CreateFactory("/Pages/Level1/Level2/_ViewStart.cshtml"))
            .Returns(new RazorPageFactoryResult(new CompiledViewDescriptor(), () => null))
            .Verifiable();
            mock
            .Setup(p => p.CreateFactory("/Pages/Level1/_ViewStart.cshtml"))
            .Returns(new RazorPageFactoryResult(new CompiledViewDescriptor(), () => null))
            .Verifiable();
            mock
            .Setup(p => p.CreateFactory("/Pages/_ViewStart.cshtml"))
            .Returns(new RazorPageFactoryResult(new CompiledViewDescriptor(), () => null))
            .Verifiable();
            mock
            .Setup(p => p.CreateFactory("/_ViewStart.cshtml"))
            .Returns(new RazorPageFactoryResult(new CompiledViewDescriptor(), () => null))
            .Verifiable();

            var razorPageFactoryProvider = mock.Object;

            var invokerProvider = CreateInvokerProvider(
                loader.Object,
                CreateActionDescriptorCollection(descriptor),
                razorPageFactoryProvider: razorPageFactoryProvider,
                razorProject: razorProject);

            // Act
            var factories = invokerProvider.GetViewStartFactories(compiledPageDescriptor);

            // Assert
            mock.Verify();
        }
コード例 #19
0
        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 factory = PagePropertyBinderFactory.CreateBinder(binder, modelMetadataProvider, 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(int), page.Id);
            Assert.Null(page.RouteDifferentValue);

            Assert.Equal(10, model.Id);
            Assert.Equal("route-value", model.RouteDifferentValue);
            Assert.Null(model.PropertyWithNoValue);
        }
 public Func <PageContext, object> CreateActivator([NotNull] CompiledPageActionDescriptor descriptor)
 {
     Check.NotNull(descriptor, nameof(descriptor));
     return(context => context.HttpContext.RequestServices.GetRequiredService(descriptor.ModelTypeInfo));
 }
コード例 #21
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);
        }
コード例 #22
0
 /// <inheritdoc />
 public Action <PageContext, object> CreateReleaser(CompiledPageActionDescriptor descriptor) => null;
コード例 #23
0
 /// <inheritdoc/>
 public Action <PageContext, object>?CreateReleaser(CompiledPageActionDescriptor descriptor)
 {
     return(null);
 }
コード例 #24
0
        public async Task BindModelAsync_WithBindPageProperty_EnforcesBindRequired(int?input, bool isValid)
        {
            // Arrange
            var propertyInfo       = typeof(TestPage).GetProperty(nameof(TestPage.BindRequiredProperty));
            var propertyDescriptor = new PageBoundPropertyDescriptor
            {
                BindingInfo = BindingInfo.GetBindingInfo(new[]
                {
                    new FromQueryAttribute {
                        Name = propertyInfo.Name
                    },
                }),
                Name          = propertyInfo.Name,
                ParameterType = propertyInfo.PropertyType,
                Property      = propertyInfo,
            };

            var typeInfo         = typeof(TestPage).GetTypeInfo();
            var actionDescriptor = new CompiledPageActionDescriptor
            {
                BoundProperties = new[] { propertyDescriptor },
                HandlerTypeInfo = typeInfo,
                ModelTypeInfo   = typeInfo,
                PageTypeInfo    = typeInfo,
            };

            var testContext = ModelBindingTestHelper.GetTestContext(request =>
            {
                request.Method = "POST";
                if (input.HasValue)
                {
                    request.QueryString = new QueryString($"?{propertyDescriptor.Name}={input.Value}");
                }
            });

            var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var parameterBinder       = ModelBindingTestHelper.GetParameterBinder(modelMetadataProvider);
            var modelBinderFactory    = ModelBindingTestHelper.GetModelBinderFactory(modelMetadataProvider);
            var modelMetadata         = modelMetadataProvider
                                        .GetMetadataForProperty(typeof(TestPage), propertyDescriptor.Name);

            var pageBinder = PageBinderFactory.CreatePropertyBinder(
                parameterBinder,
                modelMetadataProvider,
                modelBinderFactory,
                actionDescriptor);
            var pageContext = new PageContext
            {
                ActionDescriptor       = actionDescriptor,
                HttpContext            = testContext.HttpContext,
                RouteData              = testContext.RouteData,
                ValueProviderFactories = testContext.ValueProviderFactories,
            };

            var page = new TestPage();

            // Act
            await pageBinder(pageContext, page);

            // Assert
            Assert.Equal(isValid, pageContext.ModelState.IsValid);
            if (isValid)
            {
                Assert.Equal(input.Value, page.BindRequiredProperty);
            }
        }
コード例 #25
0
    public Func <PageContext, ViewContext, object, ValueTask>?CreateAsyncPageDisposer(CompiledPageActionDescriptor descriptor)
    {
        if (descriptor == null)
        {
            throw new ArgumentNullException(nameof(descriptor));
        }

        return(_pageActivator.CreateAsyncReleaser(descriptor));
    }
コード例 #26
0
        public static Func <PageContext, object, Task> CreatePropertyBinder(
            ParameterBinder parameterBinder,
            IModelMetadataProvider modelMetadataProvider,
            IModelBinderFactory modelBinderFactory,
            CompiledPageActionDescriptor actionDescriptor)
        {
            if (parameterBinder == null)
            {
                throw new ArgumentNullException(nameof(parameterBinder));
            }

            if (actionDescriptor == null)
            {
                throw new ArgumentNullException(nameof(actionDescriptor));
            }

            var properties = actionDescriptor.BoundProperties;

            if (properties == null || properties.Count == 0)
            {
                return(NullPropertyBinder);
            }

            var handlerType         = actionDescriptor.HandlerTypeInfo.AsType();
            var propertyBindingInfo = new BinderItem[properties.Count];

            for (var i = 0; i < properties.Count; i++)
            {
                var property = properties[i];
                var metadata = modelMetadataProvider.GetMetadataForProperty(handlerType, property.Name);
                var binder   = modelBinderFactory.CreateBinder(new ModelBinderFactoryContext
                {
                    BindingInfo = property.BindingInfo,
                    Metadata    = metadata,
                    CacheToken  = property,
                });

                propertyBindingInfo[i] = new BinderItem(binder, metadata);
            }

            return(Bind);

            async Task Bind(PageContext pageContext, object instance)
            {
                var valueProvider = await CompositeValueProvider.CreateAsync(pageContext, pageContext.ValueProviderFactories);

                for (var i = 0; i < properties.Count; i++)
                {
                    var property      = properties[i];
                    var bindingInfo   = propertyBindingInfo[i];
                    var modelMetadata = bindingInfo.ModelMetadata;

                    if (!modelMetadata.IsBindingAllowed)
                    {
                        continue;
                    }

                    var result = await parameterBinder.BindModelAsync(
                        pageContext,
                        bindingInfo.ModelBinder,
                        valueProvider,
                        property,
                        modelMetadata,
                        value : null);

                    if (result.IsModelSet)
                    {
                        PropertyValueSetter.SetValue(bindingInfo.ModelMetadata, instance, result.Model);
                    }
                }
            }
        }
コード例 #27
0
        public static PageHandlerBinderDelegate CreateHandlerBinder(
            ParameterBinder parameterBinder,
            IModelMetadataProvider modelMetadataProvider,
            IModelBinderFactory modelBinderFactory,
            CompiledPageActionDescriptor actionDescriptor,
            HandlerMethodDescriptor handler,
            MvcOptions mvcOptions)
        {
            if (handler.Parameters == null || handler.Parameters.Count == 0)
            {
                return(NullHandlerBinder);
            }

            var handlerType          = actionDescriptor.HandlerTypeInfo.AsType();
            var parameterBindingInfo = new BinderItem[handler.Parameters.Count];

            for (var i = 0; i < parameterBindingInfo.Length; i++)
            {
                var           parameter = handler.Parameters[i];
                ModelMetadata metadata;
                if (mvcOptions.AllowValidatingTopLevelNodes &&
                    modelMetadataProvider is ModelMetadataProvider modelMetadataProviderBase)
                {
                    // The default model metadata provider derives from ModelMetadataProvider
                    // and can therefore supply information about attributes applied to parameters.
                    metadata = modelMetadataProviderBase.GetMetadataForParameter(parameter.ParameterInfo);
                }
                else
                {
                    // For backward compatibility, if there's a custom model metadata provider that
                    // only implements the older IModelMetadataProvider interface, access the more
                    // limited metadata information it supplies. In this scenario, validation attributes
                    // are not supported on parameters.
                    metadata = modelMetadataProvider.GetMetadataForType(parameter.ParameterType);
                }

                var binder = modelBinderFactory.CreateBinder(new ModelBinderFactoryContext
                {
                    BindingInfo = parameter.BindingInfo,
                    Metadata    = metadata,
                    CacheToken  = parameter,
                });

                parameterBindingInfo[i] = new BinderItem(binder, metadata);
            }

            return(Bind);

            async Task Bind(PageContext pageContext, IDictionary <string, object> arguments)
            {
                var valueProvider = await CompositeValueProvider.CreateAsync(pageContext, pageContext.ValueProviderFactories);

                for (var i = 0; i < parameterBindingInfo.Length; i++)
                {
                    var parameter     = handler.Parameters[i];
                    var bindingInfo   = parameterBindingInfo[i];
                    var modelMetadata = bindingInfo.ModelMetadata;

                    if (!modelMetadata.IsBindingAllowed)
                    {
                        continue;
                    }

                    var result = await parameterBinder.BindModelAsync(
                        pageContext,
                        bindingInfo.ModelBinder,
                        valueProvider,
                        parameter,
                        modelMetadata,
                        value : null);

                    if (result.IsModelSet)
                    {
                        arguments[parameter.Name] = result.Model;
                    }
                }
            }
        }
コード例 #28
0
 /// <summary>
 /// 获取Html生成路径特性
 /// </summary>
 /// <param name="compiledPage">编译后的页面</param>
 private HtmlPathAttribute GetHtmlPathAttribute(CompiledPageActionDescriptor compiledPage) =>
 compiledPage.PageTypeInfo.GetCustomAttribute <HtmlPathAttribute>() ??
 compiledPage.DeclaredModelTypeInfo.GetCustomAttribute <HtmlPathAttribute>();