private async Task BindArgumentsCoreAsync()
        {
            if (CacheEntry.PropertyBinder != null)
            {
                await CacheEntry.PropertyBinder(_pageContext, _instance);
            }

            if (_handler == null)
            {
                return;
            }

            var valueProvider = await CompositeValueProvider.CreateAsync(_pageContext, _pageContext.ValueProviderFactories);

            for (var i = 0; i < _handler.Parameters.Count; i++)
            {
                var parameter = _handler.Parameters[i];

                var result = await _parameterBinder.BindModelAsync(
                    _pageContext,
                    valueProvider,
                    parameter,
                    value : null);

                if (result.IsModelSet)
                {
                    _arguments[parameter.Name] = result.Model;
                }
            }
        }
    public async Task ArrayModelBinder_ThrowsOn1025Items_AtTopLevel()
    {
        // Arrange
        var expectedMessage = "Collection bound to 'parameter' exceeded " +
                              $"{nameof(MvcOptions)}.{nameof(MvcOptions.MaxModelBindingCollectionSize)} (1024). This limit is a " +
                              $"safeguard against incorrect model binders and models. Address issues in " +
                              $"'{typeof(SuccessfulModel)}'. For example, this type may have a property with a model binder that " +
                              $"always succeeds. See the {nameof(MvcOptions)}.{nameof(MvcOptions.MaxModelBindingCollectionSize)} " +
                              "documentation for more information.";
        var parameter = new ParameterDescriptor()
        {
            Name          = "parameter",
            ParameterType = typeof(SuccessfulModel[]),
        };

        var testContext = ModelBindingTestHelper.GetTestContext(request =>
        {
            // CollectionModelBinder binds an empty collection when value providers are all empty.
            request.QueryString = new QueryString("?a=b");
        });

        var modelState    = testContext.ModelState;
        var metadata      = testContext.MetadataProvider.GetMetadataForType(parameter.ParameterType);
        var valueProvider = await CompositeValueProvider.CreateAsync(testContext);

        var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext);

        // Act & Assert
        var exception = await Assert.ThrowsAsync <InvalidOperationException>(
            () => parameterBinder.BindModelAsync(parameter, testContext));

        Assert.Equal(expectedMessage, exception.Message);
    }
        public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            try
            {
                var result        = new List <CodePoint>();
                var valueProvider = CompositeValueProvider.CreateAsync(((ControllerBase)context.Controller).ControllerContext).Result;
                var code          = valueProvider.GetValue(Field).ToString();
                if (string.IsNullOrEmpty(code))
                {
                    context.ModelState.TryAddModelError(Field, "验证码为空");
                }
                else
                {
                    var provider  = VerificationCodeFactory.GetProvider();
                    var pointList = provider.Decode(code);
                    var checkCode = provider.Decode(context.HttpContext.Session.GetString(VerificationCodeFactory.Option.SessionKey) ?? String.Empty);
                    if (checkCode?.Compare(pointList) != true)
                    {
                        context.ModelState.TryAddModelError(Field, "验证失败");
                    }
                }
            }
            catch
            {
            }

            return(next());
        }
示例#4
0
        public async Task <IHtmlContent> ContentAsync(IViewComponentHelper helper)
        {
            var actionContext     = _actionContextAccessor.ActionContext;
            var viewComponentName = actionContext.RouteData.DataTokens["ViewComponent"] as string;

            var compositeValueProvider = await CompositeValueProvider.CreateAsync(actionContext, _optionsAccessor.Value.ValueProviderFactories);

            var pluginViewComponent = _viewComponentSelector.SelectComponent(viewComponentName);
            var parameterBinder     = ActivatorUtilities.CreateInstance <ParameterBinder>(_serviceProvider);

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

            foreach (var parameter in pluginViewComponent.Parameters)
            {
                var parameterDescriptor = new ParameterDescriptor {
                    BindingInfo   = BindingInfo.GetBindingInfo(parameter.GetCustomAttributes()),
                    Name          = parameter.Name,
                    ParameterType = parameter.ParameterType,
                };

                var result = await parameterBinder.BindModelAsync(
                    actionContext,
                    compositeValueProvider,
                    parameterDescriptor);

                parameterBag[parameter.Name] = result.IsModelSet ? result.Model : null;
            }
            return(await helper.InvokeAsync(viewComponentName, parameterBag));
        }
        public static async Task <ModelBindingResult> BindModelAsync(
            this ParameterBinder parameterBinder,
            ParameterDescriptor parameter,
            ControllerContext context,
            IModelMetadataProvider modelMetadataProvider,
            ModelMetadata modelMetadata)
        {
            var valueProvider = await CompositeValueProvider.CreateAsync(context);

            var modelBinderFactory = ModelBindingTestHelper.GetModelBinderFactory(modelMetadataProvider);

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

            return(await parameterBinder.BindModelAsync(
                       context,
                       modelBinder,
                       valueProvider,
                       parameter,
                       modelMetadata,
                       value : null));
        }
        /// <summary>
        /// Reads the JSON HTTP request entity body.
        /// </summary>
        /// <param name="context">The <see cref="ResourceExecutingContext"/>.</param>
        /// <returns>
        /// A <see cref="Task"/> that on completion provides a <see cref="JObject"/> containing the HTTP request entity
        /// body.
        /// </returns>
        protected virtual async Task <JObject> ReadAsJsonAsync(ResourceExecutingContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var request = context.HttpContext.Request;

            if (request.Body == null ||
                !request.ContentLength.HasValue ||
                request.ContentLength.Value == 0L ||
                !HttpMethods.IsPost(request.Method))
            {
                // Other filters will log and return errors about these conditions.
                return(null);
            }

            var modelState    = context.ModelState;
            var actionContext = new ActionContext(
                context.HttpContext,
                context.RouteData,
                context.ActionDescriptor,
                modelState);

            var valueProviderFactories = context.ValueProviderFactories;
            var valueProvider          = await CompositeValueProvider.CreateAsync(actionContext, valueProviderFactories);

            var bindingContext = DefaultModelBindingContext.CreateBindingContext(
                actionContext,
                valueProvider,
                _jObjectMetadata,
                bindingInfo: null,
                modelName: WebHookConstants.ModelStateBodyModelName);

            // Read request body.
            try
            {
                await _bodyModelBinder.BindModelAsync(bindingContext);
            }
            finally
            {
                request.Body.Seek(0L, SeekOrigin.Begin);
            }

            if (!bindingContext.ModelState.IsValid)
            {
                return(null);
            }

            if (!bindingContext.Result.IsModelSet)
            {
                throw new InvalidOperationException(Resources.VerifyNotification_ModelBindingFailed);
            }

            // Success
            return((JObject)bindingContext.Result.Model);
        }
        public static async Task <ModelBindingResult> BindModelAsync(
            this ParameterBinder parameterBinder,
            ParameterDescriptor parameter,
            ControllerContext context)
        {
            var valueProvider = await CompositeValueProvider.CreateAsync(context);

            return(await parameterBinder.BindModelAsync(context, valueProvider, parameter));
        }
        /// <summary>
        /// Reads the HTML form URL-encoded data request entity body.
        /// </summary>
        /// <param name="context">The <see cref="ResourceExecutingContext"/>.</param>
        /// <returns>
        /// A <see cref="Task"/> that on completion provides a <see cref="IFormCollection"/> containing data from
        /// the HTTP request entity body.
        /// </returns>
        protected virtual async Task <IFormCollection> ReadAsFormDataAsync(ResourceExecutingContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var request = context.HttpContext.Request;

            if (request.Body == null ||
                !request.ContentLength.HasValue ||
                request.ContentLength.Value == 0L ||
                !HttpMethods.IsPost(request.Method) ||
                !request.HasFormContentType)
            {
                // Other filters will log and return errors about these conditions.
                return(null);
            }

            var modelState    = context.ModelState;
            var actionContext = new ActionContext(
                context.HttpContext,
                context.RouteData,
                context.ActionDescriptor,
                modelState);

            var valueProviderFactories = context.ValueProviderFactories;
            var valueProvider          = await CompositeValueProvider.CreateAsync(actionContext, valueProviderFactories);

            var bindingContext = DefaultModelBindingContext.CreateBindingContext(
                actionContext,
                valueProvider,
                _formCollectionMetadata,
                bindingInfo: null,
                modelName: WebHookConstants.ModelStateBodyModelName);

            // Read request body.
            try
            {
                await _formModelBinder.BindModelAsync(bindingContext);
            }
            finally
            {
                request.Body.Seek(0L, SeekOrigin.Begin);
            }

            // FormCollectionModelBinder cannot fail, even when !HasFormContentType (which isn't possible here).
            Debug.Assert(bindingContext.ModelState.IsValid);
            Debug.Assert(bindingContext.Result.IsModelSet);

            // Success
            return((IFormCollection)bindingContext.Result.Model);
        }
示例#9
0
        /// <inheritdocs />
        public async Task <IDictionary <string, object> > BindArgumentsAsync(WidgetContext context, MethodInfo method, IDictionary <string, object> values)
        {
            var bindingContext = new OperationBindingContext
            {
                HttpContext       = context.ViewContext.HttpContext,
                InputFormatters   = _options.InputFormatters,
                MetadataProvider  = _modelMetadataProvider,
                ModelBinder       = new CompositeModelBinder(_options.ModelBinders),
                ValidatorProvider = new CompositeModelValidatorProvider(_options.ModelValidatorProviders),
                ValueProvider     = await CompositeValueProvider.CreateAsync(_options.ValueProviderFactories, new ValueProviderFactoryContext(context.ViewContext.HttpContext, context.ViewContext.RouteData.Values))
            };

            var arguments  = new Dictionary <string, object>(StringComparer.Ordinal);
            var parameters = method.GetParameters();

            foreach (var parameter in parameters)
            {
                if (values.ContainsKey(parameter.Name))
                {
                    arguments.Add(parameter.Name, values[parameter.Name]);
                }
                else
                {
                    var attribute   = parameter.GetCustomAttributes().OfType <IBindingSourceMetadata>().FirstOrDefault();
                    var bindingInfo = new BindingInfo()
                    {
                        BindingSource = attribute?.BindingSource
                    };

                    var metadata            = _modelMetadataProvider.GetMetadataForType(parameter.ParameterType);
                    var modelBindingContext = ModelBindingContext.CreateBindingContext(
                        bindingContext,
                        context.ModelState,
                        metadata,
                        bindingInfo,
                        parameter.Name);

                    var result = await bindingContext.ModelBinder.BindModelAsync(modelBindingContext);

                    if (result.IsModelSet)
                    {
                        _objectModelValidator.Validate(bindingContext.ValidatorProvider, context.ModelState, modelBindingContext.ValidationState, result.Key, result.Model);
                        arguments.Add(parameter.Name, result.Model);
                    }
                    else
                    {
                        arguments.Add(parameter.Name, Activator.CreateInstance(parameter.ParameterType));
                    }
                }
            }

            return(arguments);
        }
        public async Task <T> Bind <T>(HttpRequest request) where T : new()
        {
            //always rewind the stream; otherwise,
            //if multiple handlers concurrently bind
            //different models only the first one succeeds
            request.Body.Position = 0;

            var modelType     = typeof(T);
            var modelMetadata = modelMetadataProvider.GetMetadataForType(modelType);
            var actionContext = new ActionContext(
                request.HttpContext,
                request.HttpContext.GetRouteData(),
                new ActionDescriptor(),
                new ModelStateDictionary());
            var valueProvider =
                await CompositeValueProvider.CreateAsync(actionContext, mvcOptions.Value.ValueProviderFactories);

#if NET5_0
            if (modelMetadata.BoundConstructor != null)
            {
                throw new NotSupportedException("Record type not supported");
            }
#endif

            var modelBindingContext = DefaultModelBindingContext.CreateBindingContext(
                actionContext,
                valueProvider,
                modelMetadata,
                bindingInfo: null,
                modelName: "");

            modelBindingContext.Model          = new T();
            modelBindingContext.PropertyFilter = _ => true; // All props

            var factoryContext = new ModelBinderFactoryContext()
            {
                Metadata    = modelMetadata,
                BindingInfo = new BindingInfo()
                {
                    BinderModelName        = modelMetadata.BinderModelName,
                    BinderType             = modelMetadata.BinderType,
                    BindingSource          = modelMetadata.BindingSource,
                    PropertyFilterProvider = modelMetadata.PropertyFilterProvider,
                },
                CacheToken = modelMetadata,
            };

            await modelBinderFactory
            .CreateBinder(factoryContext)
            .BindModelAsync(modelBindingContext);

            return((T)modelBindingContext.Result.Model);
        }
        /// <summary>
        /// Reads the XML HTTP request entity body.
        /// </summary>
        /// <param name="context">The <see cref="ResourceExecutingContext"/>.</param>
        /// <returns>
        /// A <see cref="Task"/> that on completion provides a <see cref="XElement"/> containing the HTTP request
        /// entity body.
        /// </returns>
        protected virtual async Task <XElement> ReadAsXmlAsync(ResourceExecutingContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var request = context.HttpContext.Request;

            if (request.Body == null ||
                !request.ContentLength.HasValue ||
                request.ContentLength.Value == 0L ||
                !HttpMethods.IsPost(request.Method) ||
                !request.IsXml())
            {
                // Other filters will log and return errors about these conditions.
                return(null);
            }

            var modelState    = context.ModelState;
            var actionContext = new ActionContext(
                context.HttpContext,
                context.RouteData,
                context.ActionDescriptor,
                modelState);

            var valueProviderFactories = context.ValueProviderFactories;
            var valueProvider          = await CompositeValueProvider.CreateAsync(actionContext, valueProviderFactories);

            var bindingContext = DefaultModelBindingContext.CreateBindingContext(
                actionContext,
                valueProvider,
                _xElementMetadata,
                bindingInfo: null,
                modelName: ModelStateRootKey);

            // Read request body.
            await _bodyModelBinder.BindModelAsync(bindingContext);

            if (!bindingContext.ModelState.IsValid)
            {
                return(null);
            }

            if (!bindingContext.Result.IsModelSet)
            {
                throw new InvalidOperationException(Resources.VerifyOrganization_ModelBindingFailed);
            }

            // Success
            return((XElement)bindingContext.Result.Model);
        }
示例#12
0
        private static ActionBindingContext GetActionBindingContext(MvcOptions options, ActionContext actionContext)
        {
            var valueProviderFactoryContext = new ValueProviderFactoryContext(actionContext.HttpContext, actionContext.RouteData.Values);
            var valueProvider = CompositeValueProvider.CreateAsync(options.ValueProviderFactories, valueProviderFactoryContext).Result;

            return(new ActionBindingContext()
            {
                InputFormatters = options.InputFormatters,
                OutputFormatters = options.OutputFormatters,
                ValidatorProvider = new CompositeModelValidatorProvider(options.ModelValidatorProviders),
                ModelBinder = new CompositeModelBinder(options.ModelBinders),
                ValueProvider = valueProvider
            });
        }
示例#13
0
        public override async Task OnActionExecutionAsync(ActionExecutingContext filterContext, ActionExecutionDelegate next)
        {
            IServiceProvider  serviceProvider   = filterContext.HttpContext.RequestServices;
            ControllerContext controllerContext = ((Controller)filterContext.Controller).ControllerContext;
            IValueProvider    valueProvider     = await CompositeValueProvider.CreateAsync(controllerContext);

            var stringEntityIDs = new List <string>();

            if (int.TryParse(valueProvider.GetValue(_entitySingleIdParamName).FirstValue, out int entityId))
            {
                stringEntityIDs.Add(entityId.ToString());
            }
            else
            {
                if (filterContext.ActionArguments.ContainsKey(_entityMultiIdParamName))
                {
                    if (filterContext.ActionArguments[_entityMultiIdParamName] is SelectedItemsViewModel selModel)
                    {
                        stringEntityIDs.AddRange(selModel.Ids.Select(id => id.ToString()));
                    }
                }
            }

            int?parentEntityId = null;

            if (int.TryParse(valueProvider.GetValue(_parentEntityIdParamName).FirstValue, out int parentId))
            {
                parentEntityId = parentId;
            }

            string actionCode = _actionCode;

            if (actionCode == null)
            {
                var getActionCode = serviceProvider.GetRequiredService <Func <string, IActionCode> >();
                var command       = (string)filterContext.RouteData.Values["command"];
                actionCode = getActionCode(command).ActionCode;
            }

            BackendActionContext.SetCurrent(actionCode, stringEntityIDs, parentEntityId);

            try
            {
                await next.Invoke();
            }
            finally
            {
                BackendActionContext.ResetCurrent();
            }
        }
        private async Task BindArgumentsCoreAsync(
            ControllerContext controllerContext,
            object controller,
            IDictionary <string, object> arguments)
        {
            var valueProvider = await CompositeValueProvider.CreateAsync(controllerContext);

            var parameters = controllerContext.ActionDescriptor.Parameters;

            for (var i = 0; i < parameters.Count; i++)
            {
                var parameter = parameters[i];

                var result = await BindModelAsync(parameter, controllerContext, valueProvider);

                if (result.IsModelSet)
                {
                    arguments[parameter.Name] = result.Model;
                }
            }

            var properties = controllerContext.ActionDescriptor.BoundProperties;

            if (properties.Count == 0)
            {
                // Perf: Early exit to avoid PropertyHelper lookup in the (common) case where we have no
                // bound properties.
                return;
            }

            var propertyHelpers = PropertyHelper.GetProperties(controller);

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

                var result = await BindModelAsync(property, controllerContext, valueProvider);

                if (result.IsModelSet)
                {
                    var propertyHelper = FindPropertyHelper(propertyHelpers, property);
                    if (propertyHelper != null)
                    {
                        ActivateProperty(property, propertyHelper, controller, result.Model);
                    }
                }
            }
        }
示例#15
0
        public override async Task OnActionExecutionAsync(ActionExecutingContext filterContext, ActionExecutionDelegate next)
        {
            // if (!(filterContext.HttpContext.User.Identity is QpIdentity identity) || !identity.IsAuthenticated)
            // {
            //     throw new SecurityException(GlobalStrings.YouAreNotAuthenticated);
            // }

            IServiceProvider  serviceProvider   = filterContext.HttpContext.RequestServices;
            ControllerContext controllerContext = ((Controller)filterContext.Controller).ControllerContext;
            IValueProvider    valueProvider     = await CompositeValueProvider.CreateAsync(controllerContext);

            var entityIdResult = valueProvider.GetValue(_entityIdParamName);

            if (string.IsNullOrEmpty(entityIdResult.FirstValue))
            {
                throw new ArgumentException($"Entity id field is not found: {_entityIdParamName}");
            }

            if (!int.TryParse(entityIdResult.FirstValue, out var entityId))
            {
                throw new ArgumentException($"Entity id is not a number: {entityIdResult.FirstValue}");
            }

            var entityType = EntityTypeService.GetByCode(_entityTypeCode);

            if (entityType == null)
            {
                throw new ArgumentException($"Unknown entity type: {_entityTypeCode}");
            }

            var actionType = BackendActionTypeService.GetByCode(_actionTypeCode);

            if (actionType == null)
            {
                throw new ArgumentException($"Unknown action type: {_actionTypeCode}");
            }

            var securityService = serviceProvider.GetRequiredService <ISecurityService>();

            if (!securityService.IsEntityAccessible(_entityTypeCode, entityId, _actionTypeCode))
            {
                throw new SecurityException(string.Format(
                                                GlobalStrings.EntityIsNotAccessible, actionType.Name, entityType.Name, entityId));
            }

            await next.Invoke();
        }
        private async Task <bool> TryUpdateModelAsync(
            object model,
            string prefix,
            ModelBindingTestContext testContext)
        {
            var valueProvider = await CompositeValueProvider.CreateAsync(testContext);

            return(await ModelBindingHelper.TryUpdateModelAsync(
                       model,
                       model.GetType(),
                       prefix,
                       testContext,
                       testContext.MetadataProvider,
                       TestModelBinderFactory.CreateDefault(),
                       valueProvider,
                       ModelBindingTestHelper.GetObjectValidator(testContext.MetadataProvider)));
        }
        public async Task <ModelBindingResult> BindModelAsync(
            ParameterDescriptor parameter,
            ControllerContext controllerContext)
        {
            if (parameter == null)
            {
                throw new ArgumentNullException(nameof(parameter));
            }

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

            var valueProvider = await CompositeValueProvider.CreateAsync(controllerContext);

            return(await BindModelAsync(parameter, controllerContext, valueProvider));
        }
示例#18
0
        // POSTされたGeometryTypeの値によって、生成するモデルを切り替える
        private async Task <GeometryModel> CreateModel()
        {
            var valueProvider = await CompositeValueProvider.CreateAsync(ControllerContext);

            // POSTされたデータの中から"GeometryType"の値を取得
            var valueProviderResult = valueProvider.GetValue(nameof(GeometryModel.GeometryType));

            // 文字列をenumに変換
            if (!Enum.TryParse <GeometryType>(valueProviderResult.FirstValue, true, out var geometryType))
            {
                throw new InvalidOperationException();
            }

            // enumからモデルの型を取得
            var modelType = geometryType.GetModelType();

            // モデルを生成
            return((GeometryModel)Activator.CreateInstance(modelType));
        }
示例#19
0
        private static async Task BindPropertiesAsync(
            ParameterBinder parameterBinder,
            PageContext pageContext,
            object instance,
            IList <ParameterDescriptor> properties,
            IList <ModelMetadata> metadata)
        {
            var valueProvider = await CompositeValueProvider.CreateAsync(pageContext, pageContext.ValueProviderFactories);

            for (var i = 0; i < properties.Count; i++)
            {
                var result = await parameterBinder.BindModelAsync(pageContext, valueProvider, properties[i]);

                if (result.IsModelSet)
                {
                    PropertyValueSetter.SetValue(metadata[i], instance, result.Model);
                }
            }
        }
示例#20
0
        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement)
        {
            var mvcContext = context.Resource as AuthorizationFilterContext;
            //required service
            var _mvcOptions            = mvcContext.HttpContext.RequestServices.GetRequiredService <IOptions <MvcOptions> >().Value;
            var parameterBinder        = mvcContext.HttpContext.RequestServices.GetRequiredService <ParameterBinder>();
            var _modelBinderFactory    = mvcContext.HttpContext.RequestServices.GetRequiredService <IModelBinderFactory>();
            var _modelMetadataProvider = mvcContext.HttpContext.RequestServices.GetRequiredService <IModelMetadataProvider>();

            var controllerContext = new ControllerContext(mvcContext);

            controllerContext.ValueProviderFactories = new CopyOnWriteList <IValueProviderFactory>(_mvcOptions.ValueProviderFactories.ToArray());
            var valueProvider = await CompositeValueProvider.CreateAsync(controllerContext);

            var parameters           = controllerContext.ActionDescriptor.Parameters;
            var parameterBindingInfo = GetParameterBindingInfo(
                _modelBinderFactory,
                _modelMetadataProvider,
                controllerContext.ActionDescriptor,
                _mvcOptions);

            for (var i = 0; i < parameters.Count; i++)
            {
                var parameter     = parameters[i];
                var bindingInfo   = parameterBindingInfo[i];
                var modelMetadata = bindingInfo.ModelMetadata;

                if (!modelMetadata.IsBindingAllowed)
                {
                    continue;
                }

                var model = await parameterBinder.BindModelAsync(
                    controllerContext,
                    bindingInfo.ModelBinder,
                    valueProvider,
                    parameter,
                    modelMetadata,
                    value : null);
            }
        }
示例#21
0
        public static ControllerBinderDelegate CreateBinderDelegate(
            ParameterBinder parameterBinder,
            IModelBinderFactory modelBinderFactory,
            IModelMetadataProvider modelMetadataProvider,
            ControllerActionDescriptor actionDescriptor,
            MvcOptions mvcOptions)
        {
            if (parameterBinder == null)
            {
                throw new ArgumentNullException(nameof(parameterBinder));
            }

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

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

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

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

            var parameterBindingInfo = GetParameterBindingInfo(
                modelBinderFactory,
                modelMetadataProvider,
                actionDescriptor,
                mvcOptions);
            var propertyBindingInfo = GetPropertyBindingInfo(modelBinderFactory, modelMetadataProvider, actionDescriptor);

            if (parameterBindingInfo == null && propertyBindingInfo == null)
            {
                return(null);
            }

            return(Bind);

            async Task Bind(ControllerContext controllerContext, object controller, Dictionary <string, object> arguments)
            {
                var valueProvider = await CompositeValueProvider.CreateAsync(controllerContext);

                var parameters = actionDescriptor.Parameters;

                for (var i = 0; i < parameters.Count; i++)
                {
                    var parameter     = parameters[i];
                    var bindingInfo   = parameterBindingInfo[i];
                    var modelMetadata = bindingInfo.ModelMetadata;

                    if (!modelMetadata.IsBindingAllowed)
                    {
                        continue;
                    }

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

                    if (result.IsModelSet)
                    {
                        arguments[parameter.Name] = result.Model;
                    }
                }

                var properties = actionDescriptor.BoundProperties;

                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(
                        controllerContext,
                        bindingInfo.ModelBinder,
                        valueProvider,
                        property,
                        modelMetadata,
                        value : null);

                    if (result.IsModelSet)
                    {
                        PropertyValueSetter.SetValue(bindingInfo.ModelMetadata, controller, result.Model);
                    }
                }
            }
        }
示例#22
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;
                    }
                }
            }
        }
示例#23
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);
                    }
                }
            }
        }
        GetBindingInfo(ActionDescriptor actionDescriptor, RouteContext routeContext)
        {
            if (actionDescriptor == null)
            {
                throw new ArgumentNullException(nameof(actionDescriptor));
            }

            var bindingResult = (new Dictionary <string, object>(), new Dictionary <ModelMetadata, object>());

            var parameterBindingInfo =
                GetParameterBindingInfo(
                    modelBinderFactory,
                    modelMetadataProvider,
                    actionDescriptor,
                    mvcOptions);

            BinderItem[] propertyBindingInfo = null;
            if (actionDescriptor is ControllerActionDescriptor)
            {
                propertyBindingInfo =
                    GetPropertyBindingInfo(
                        modelBinderFactory,
                        modelMetadataProvider,
                        actionDescriptor as ControllerActionDescriptor);
            }

            if (parameterBindingInfo == null && propertyBindingInfo == null)
            {
                return(bindingResult);
            }

            //Bind(ControllerContext controllerContext, object controller, Dictionary<string, object> arguments)

            var actionContext = new ActionContext(routeContext.HttpContext, routeContext.RouteData, actionDescriptor);

            var controllerContext = new ControllerContext(actionContext)
            {
                ValueProviderFactories =
                    new CopyOnWriteList <IValueProviderFactory>(mvcOptions.ValueProviderFactories.ToArray()),
            };

            controllerContext.ModelState.MaxAllowedErrors = mvcOptions.MaxModelValidationErrors;

            var valueProvider = await CompositeValueProvider.CreateAsync(controllerContext);

            var parameters = actionDescriptor.Parameters;

            if (parameterBindingInfo != null)
            {
                for (var i = 0; i < parameters.Count; i++)
                {
                    var parameter     = parameters[i];
                    var bindingInfo   = parameterBindingInfo[i];
                    var modelMetadata = bindingInfo.ModelMetadata;

                    if (!modelMetadata.IsBindingAllowed)
                    {
                        continue;
                    }

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

                    if (result.IsModelSet)
                    {
                        bindingResult.Item1[parameter.Name] = result.Model;
                    }
                }
            }

            var properties = actionDescriptor.BoundProperties;

            if (propertyBindingInfo != null && properties != null)
            {
                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(
                        controllerContext,
                        bindingInfo.ModelBinder,
                        valueProvider,
                        property,
                        modelMetadata,
                        value : null);

                    if (result.IsModelSet)
                    {
                        //PropertyValueSetter.SetValue(bindingInfo.ModelMetadata, controller, result.Model);
                        bindingResult.Item2[bindingInfo.ModelMetadata] = result.Model;
                    }
                }
            }
            return(bindingResult);
        }
示例#25
0
        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement)
        {
            var mvcContext             = context.Resource as AuthorizationFilterContext;
            var _modelBinderFactory    = mvcContext.HttpContext.RequestServices.GetRequiredService <IModelBinderFactory>();
            var _modelMetadataProvider = mvcContext.HttpContext.RequestServices.GetRequiredService <IModelMetadataProvider>();
            var _mvcOptions            = mvcContext.HttpContext.RequestServices.GetRequiredService <IOptions <MvcOptions> >().Value;

            //var parameters =
            //              mvcContext
            //                .ActionDescriptor
            //                .Parameters
            //                .Select(s => new
            //                {
            //                    Name = s.Name,
            //                    Value = mvcContext.HttpContext.Request.Query[s.Name]
            //                });

            //object Result = Activator.CreateInstance(typeof(List<MembershipType>));

            //Result.GetType().GetMethod("Add").Invoke(Result, new object[] { MembershipType.Admin });
            ////// TODO: need access to query parameters here
            var controllerContext = new ControllerContext(mvcContext);

            var controllerActionInvokerCache = mvcContext.HttpContext.RequestServices.GetRequiredService <ControllerActionInvokerCache>();
            var cacheResult = controllerActionInvokerCache.GetCachedResult(controllerContext);
            var controller  = cacheResult.cacheEntry.ControllerFactory.Invoke(controllerContext) as Controller;
            var model       = new List <MembershipType>();
            await controller.TryUpdateModelAsync(model);


            var parameterBinder = mvcContext.HttpContext.RequestServices.GetRequiredService <ParameterBinder>();

            //var rr = await parameterBinder.BindModelAsync(
            //                    controllerContext,
            //                    controllerContext.,
            //                    valueProvider,
            //                    parameter,
            //                    modelMetadata,
            //                    value: null);

            //var parameters = controllerContext.ActionDescriptor.Parameters;

            //for (var i = 0; i < parameters.Count; i++)
            //{
            //    var parameter = parameters[i];
            //    var bindingInfo = parameterBindingInfo[i];
            //    var modelMetadata = bindingInfo.ModelMetadata;

            //    if (!modelMetadata.IsBindingAllowed)
            //    {
            //        continue;
            //    }

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

            //    if (result.IsModelSet)
            //    {
            //        arguments[parameter.Name] = result.Model;
            //    }
            //}


            //var propertyBinderFactory = ControllerBinderDelegateProvider.CreateBinderDelegate(
            //                     parameterBinder,
            //                     _modelBinderFactory,
            //                     _modelMetadataProvider,
            //                     controllerContext.ActionDescriptor,
            //                     _mvcOptions);
            var parameterBindingInfo = GetParameterBindingInfo(
                _modelBinderFactory,
                _modelMetadataProvider,
                controllerContext.ActionDescriptor,
                _mvcOptions);

            controllerContext.ValueProviderFactories = new CopyOnWriteList <IValueProviderFactory>(_mvcOptions.ValueProviderFactories.ToArray());

            var valueProvider = await CompositeValueProvider.CreateAsync(controllerContext);

            var parameters = controllerContext.ActionDescriptor.Parameters;



            for (var i = 0; i < parameters.Count; i++)
            {
                var parameter     = parameters[i];
                var bindingInfo   = parameterBindingInfo[i];
                var modelMetadata = bindingInfo.ModelMetadata;

                if (!modelMetadata.IsBindingAllowed)
                {
                    continue;
                }

                var rr = await parameterBinder.BindModelAsync(
                    controllerContext,
                    bindingInfo.ModelBinder,
                    valueProvider,
                    parameter,
                    modelMetadata,
                    value : null);
            }
        }
示例#26
0
        private async Task <ResourceExecutedContext> InvokeResourceFilterAsync()
        {
            Debug.Assert(_resourceExecutingContext != null);

            if (_resourceExecutingContext.Result != null)
            {
                // If we get here, it means that an async filter set a result AND called next(). This is forbidden.
                var message = Resources.FormatAsyncResourceFilter_InvalidShortCircuit(
                    typeof(IAsyncResourceFilter).Name,
                    nameof(ResourceExecutingContext.Result),
                    typeof(ResourceExecutingContext).Name,
                    typeof(ResourceExecutionDelegate).Name);

                throw new InvalidOperationException(message);
            }

            var item = _cursor.GetNextFilter <IResourceFilter, IAsyncResourceFilter>();

            try
            {
                if (item.FilterAsync != null)
                {
                    _diagnosticSource.BeforeOnResourceExecution(
                        _resourceExecutingContext,
                        item.FilterAsync);

                    await item.FilterAsync.OnResourceExecutionAsync(
                        _resourceExecutingContext,
                        InvokeResourceFilterAsync);

                    _diagnosticSource.AfterOnResourceExecution(
                        _resourceExecutingContext.ActionDescriptor,
                        _resourceExecutedContext,
                        item.FilterAsync);

                    if (_resourceExecutedContext == null)
                    {
                        // If we get here then the filter didn't call 'next' indicating a short circuit
                        if (_resourceExecutingContext.Result != null)
                        {
                            Logger.LogVerbose(
                                ResourceFilterShortCircuitLogMessage,
                                item.FilterAsync.GetType().FullName);

                            await InvokeResultAsync(_resourceExecutingContext.Result);
                        }

                        _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters)
                        {
                            Canceled = true,
                            Result   = _resourceExecutingContext.Result,
                        };
                    }
                }
                else if (item.Filter != null)
                {
                    _diagnosticSource.BeforeOnResourceExecuting(
                        _resourceExecutingContext,
                        item.Filter);

                    item.Filter.OnResourceExecuting(_resourceExecutingContext);

                    _diagnosticSource.AfterOnResourceExecuting(
                        _resourceExecutingContext,
                        item.Filter);

                    if (_resourceExecutingContext.Result != null)
                    {
                        // Short-circuited by setting a result.
                        Logger.LogVerbose(ResourceFilterShortCircuitLogMessage, item.Filter.GetType().FullName);

                        await InvokeResultAsync(_resourceExecutingContext.Result);

                        _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters)
                        {
                            Canceled = true,
                            Result   = _resourceExecutingContext.Result,
                        };
                    }
                    else
                    {
                        _diagnosticSource.BeforeOnResourceExecuted(
                            _resourceExecutingContext.ActionDescriptor,
                            _resourceExecutedContext,
                            item.Filter);

                        item.Filter.OnResourceExecuted(await InvokeResourceFilterAsync());

                        _diagnosticSource.AfterOnResourceExecuted(
                            _resourceExecutingContext.ActionDescriptor,
                            _resourceExecutedContext,
                            item.Filter);
                    }
                }
                else
                {
                    // We've reached the end of resource filters, so move to setting up state to invoke model
                    // binding.
                    ActionBindingContext = new ActionBindingContext();
                    ActionBindingContext.InputFormatters   = _resourceExecutingContext.InputFormatters;
                    ActionBindingContext.OutputFormatters  = _resourceExecutingContext.OutputFormatters;
                    ActionBindingContext.ModelBinder       = new CompositeModelBinder(_resourceExecutingContext.ModelBinders);
                    ActionBindingContext.ValidatorProvider = new CompositeModelValidatorProvider(
                        _resourceExecutingContext.ValidatorProviders);

                    var valueProviderFactoryContext = new ValueProviderFactoryContext(
                        ActionContext.HttpContext,
                        ActionContext.RouteData.Values);

                    ActionBindingContext.ValueProvider = await CompositeValueProvider.CreateAsync(
                        _resourceExecutingContext.ValueProviderFactories,
                        valueProviderFactoryContext);

                    // >> ExceptionFilters >> Model Binding >> ActionFilters >> Action
                    await InvokeAllExceptionFiltersAsync();

                    // If Exception Filters provide a result, it's a short-circuit due to an exception.
                    // We don't execute Result Filters around the result.
                    Debug.Assert(_exceptionContext != null);
                    if (_exceptionContext.Result != null)
                    {
                        // This means that exception filters returned a result to 'handle' an error.
                        // We're not interested in seeing the exception details since it was handled.
                        await InvokeResultAsync(_exceptionContext.Result);

                        _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters)
                        {
                            Result = _exceptionContext.Result,
                        };
                    }
                    else if (_exceptionContext.Exception != null)
                    {
                        // If we get here, this means that we have an unhandled exception.
                        // Exception filted didn't handle this, so send it on to resource filters.
                        _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters);

                        // Preserve the stack trace if possible.
                        _resourceExecutedContext.Exception = _exceptionContext.Exception;
                        if (_exceptionContext.ExceptionDispatchInfo != null)
                        {
                            _resourceExecutedContext.ExceptionDispatchInfo = _exceptionContext.ExceptionDispatchInfo;
                        }
                    }
                    else
                    {
                        // We have a successful 'result' from the action or an Action Filter, so run
                        // Result Filters.
                        Debug.Assert(_actionExecutedContext != null);
                        var result = _actionExecutedContext.Result;

                        // >> ResultFilters >> (Result)
                        await InvokeAllResultFiltersAsync(result);

                        _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters)
                        {
                            Result = _resultExecutedContext.Result,
                        };
                    }
                }
            }
            catch (Exception exception)
            {
                _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters)
                {
                    ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception)
                };
            }

            Debug.Assert(_resourceExecutedContext != null);
            return(_resourceExecutedContext);
        }
示例#27
0
        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }

            var modelName = bindingContext.ModelName;

            var valueProvider = await CompositeValueProvider.CreateAsync(bindingContext.ActionContext, new Internal.CopyOnWriteList <IValueProviderFactory>(_valueProviderFactories));

            JObject model = bindingContext.Model != null ? (JObject)bindingContext.Model : new JObject();

            //Form/Route/Query
            if (bindingContext.ModelMetadata.BindingSource == null || bindingContext.ModelMetadata.BindingSource.CanAcceptDataFrom(BindingSource.Form) || bindingContext.ModelMetadata.BindingSource.CanAcceptDataFrom(BindingSource.Query) || bindingContext.ModelMetadata.BindingSource.CanAcceptDataFrom(BindingSource.Path))
            {
                model = ParseProperties(modelName, valueProvider, model);
            }

            //Route
            if (bindingContext.IsTopLevelObject)
            {
                if (bindingContext.ModelMetadata.BindingSource == null || bindingContext.ModelMetadata.BindingSource.CanAcceptDataFrom(BindingSource.Path))
                {
                    foreach (var kvp in bindingContext.ActionContext.RouteData.Values)
                    {
                        if (kvp.Key != "area" && kvp.Key != "controller" && kvp.Key != "action" && !model.ContainsKey(kvp.Key))
                        {
                            var stringValue = kvp.Value as string ?? Convert.ToString(kvp.Value, CultureInfo.InvariantCulture) ?? string.Empty;
                            if (!model.ContainsKey(kvp.Key))
                            {
                                model.Add(kvp.Key, GetValue(stringValue));
                            }
                            else if (bindingContext.HttpContext.Request.Query.ContainsKey(kvp.Key) && !bindingContext.HttpContext.Request.Form.ContainsKey(kvp.Key))
                            {
                                model[kvp.Key] = GetValue(stringValue);
                            }
                        }
                    }
                }
            }

            //Query
            if (bindingContext.IsTopLevelObject)
            {
                if (bindingContext.ModelMetadata.BindingSource == null || bindingContext.ModelMetadata.BindingSource.CanAcceptDataFrom(BindingSource.Query))
                {
                    foreach (var kvp in bindingContext.HttpContext.Request.Query)
                    {
                        if (!model.ContainsKey(kvp.Key))
                        {
                            model.Add(kvp.Key, GetValue(kvp.Value));
                        }
                        else if (!bindingContext.HttpContext.Request.Form.ContainsKey(kvp.Key) && !bindingContext.ActionContext.RouteData.Values.ContainsKey(kvp.Key))
                        {
                            model[kvp.Key] = GetValue(kvp.Value);
                        }
                    }
                }
            }

            bindingContext.Result = ModelBindingResult.Success(model);
        }