Пример #1
0
        /// <summary>
        /// Creates a new <see cref="ModelBindingContext"/> for top-level model binding operation.
        /// </summary>
        /// <param name="operationBindingContext">
        /// The <see cref="OperationBindingContext"/> associated with the binding operation.
        /// </param>
        /// <param name="metadata"><see cref="ModelMetadata"/> associated with the model.</param>
        /// <param name="bindingInfo"><see cref="BindingInfo"/> associated with the model.</param>
        /// <param name="modelName">The name of the property or parameter being bound.</param>
        /// <returns>A new instance of <see cref="ModelBindingContext"/>.</returns>
        public static ModelBindingContext CreateBindingContext(
            [NotNull] OperationBindingContext operationBindingContext,
            [NotNull] ModelStateDictionary modelState,
            [NotNull] ModelMetadata metadata,
            BindingInfo bindingInfo,
            [NotNull] string modelName)
        {
            var binderModelName = bindingInfo?.BinderModelName ?? metadata.BinderModelName;
            var propertyPredicateProvider =
                bindingInfo?.PropertyBindingPredicateProvider ?? metadata.PropertyBindingPredicateProvider;

            return new ModelBindingContext()
            {
                BinderModelName = binderModelName,
                BindingSource = bindingInfo?.BindingSource ?? metadata.BindingSource,
                BinderType = bindingInfo?.BinderType ?? metadata.BinderType,
                PropertyFilter = propertyPredicateProvider?.PropertyFilter,

                // We only support fallback to empty prefix in cases where the model name is inferred from
                // the parameter or property being bound.
                FallbackToEmptyPrefix = binderModelName == null,

                // Because this is the top-level context, FieldName and ModelName should be the same.
                FieldName = binderModelName ?? modelName,
                ModelName = binderModelName ?? modelName,

                IsTopLevelObject = true,
                ModelMetadata = metadata,
                ModelState = modelState,
                OperationBindingContext = operationBindingContext,
                ValueProvider = operationBindingContext.ValueProvider,

                ValidationState = new ValidationStateDictionary(),
            };
        }
Пример #2
0
        /// <summary>
        /// Creates a copy of a <see cref="BindingInfo"/>.
        /// </summary>
        /// <param name="other">The <see cref="BindingInfo"/> to copy.</param>
        public BindingInfo(BindingInfo other)
        {
            if (other == null)
            {
                throw new ArgumentNullException(nameof(other));
            }

            BindingSource = other.BindingSource;
            BinderModelName = other.BinderModelName;
            BinderType = other.BinderType;
            PropertyBindingPredicateProvider = other.PropertyBindingPredicateProvider;
        }
        /// <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;
        }
Пример #4
0
        /// <summary>
        /// Constructs a new instance of <see cref="BindingInfo"/> from the given <paramref name="attributes"/>.
        /// </summary>
        /// <param name="attributes">A collection of attributes which are used to construct <see cref="BindingInfo"/>
        /// </param>
        /// <returns>A new instance of <see cref="BindingInfo"/>.</returns>
        public static BindingInfo GetBindingInfo(IEnumerable<object> attributes)
        {
            var bindingInfo = new BindingInfo();
            var isBindingInfoPresent = false;

            // BinderModelName
            foreach (var binderModelNameAttribute in attributes.OfType<IModelNameProvider>())
            {
                isBindingInfoPresent = true;
                if (binderModelNameAttribute?.Name != null)
                {
                    bindingInfo.BinderModelName = binderModelNameAttribute.Name;
                    break;
                }
            }

            // BinderType
            foreach (var binderTypeAttribute in attributes.OfType<IBinderTypeProviderMetadata>())
            {
                isBindingInfoPresent = true;
                if (binderTypeAttribute.BinderType != null)
                {
                    bindingInfo.BinderType = binderTypeAttribute.BinderType;
                    break;
                }
            }

            // BindingSource
            foreach (var bindingSourceAttribute in attributes.OfType<IBindingSourceMetadata>())
            {
                isBindingInfoPresent = true;
                if (bindingSourceAttribute.BindingSource != null)
                {
                    bindingInfo.BindingSource = bindingSourceAttribute.BindingSource;
                    break;
                }
            }

            // PropertyBindingPredicateProvider
            var predicateProviders = attributes.OfType<IPropertyBindingPredicateProvider>().ToArray();
            if (predicateProviders.Length > 0)
            {
                isBindingInfoPresent = true;
                bindingInfo.PropertyBindingPredicateProvider = new CompositePredicateProvider(
                    predicateProviders);
            }

            return isBindingInfoPresent ? bindingInfo : null;
        }
Пример #5
0
 /// <summary>
 /// Constructs a new instance of <see cref="ModelBindingContext"/> from given <paramref name="metadata"/>
 /// and <paramref name="bindingInfo"/>.
 /// </summary>
 /// <param name="metadata"><see cref="ModelMetadata"/> associated with the model.</param>
 /// <param name="bindingInfo"><see cref="BindingInfo"/> associated with the model.</param>
 /// <param name="modelName">An optional name of the model to be used.</param>
 /// <returns>A new instance of <see cref="ModelBindingContext"/>.</returns>
 public static ModelBindingContext GetModelBindingContext(
     [NotNull] ModelMetadata metadata,
     BindingInfo bindingInfo,
     string modelName)
 {
     var binderModelName = bindingInfo?.BinderModelName ?? metadata.BinderModelName;
     var propertyPredicateProvider =
         bindingInfo?.PropertyBindingPredicateProvider ?? metadata.PropertyBindingPredicateProvider;
     return new ModelBindingContext
     {
         ModelMetadata = metadata,
         BindingSource = bindingInfo?.BindingSource ?? metadata.BindingSource,
         PropertyFilter = propertyPredicateProvider?.PropertyFilter,
         BinderType = bindingInfo?.BinderType ?? metadata.BinderType,
         BinderModelName = binderModelName,
         ModelName = binderModelName ?? metadata.PropertyName ?? modelName,
         FallbackToEmptyPrefix = binderModelName == null,
     };
 }
        private static ModelBindingContext GetModelBindingContext(
            string parameterName,
            ModelMetadata metadata,
            BindingInfo bindingInfo,
            ModelStateDictionary modelState,
            OperationBindingContext operationBindingContext)
        {
            var modelBindingContext = ModelBindingContext.GetModelBindingContext(
                metadata,
                bindingInfo,
                parameterName);

            modelBindingContext.ModelState = modelState;
            modelBindingContext.ValueProvider = operationBindingContext.ValueProvider;
            modelBindingContext.OperationBindingContext = operationBindingContext;

            return modelBindingContext;
        }