public async Task <ModelBindingResult> BindModelAsync(
            [NotNull] ParameterDescriptor parameter,
            [NotNull] ModelStateDictionary modelState,
            [NotNull] OperationBindingContext operationContext)
        {
            var metadata            = _modelMetadataProvider.GetMetadataForType(parameter.ParameterType);
            var modelBindingContext = ModelBindingContext.CreateBindingContext(
                operationContext,
                modelState,
                metadata,
                parameter.BindingInfo,
                parameter.Name);

            var modelBindingResult = await operationContext.ModelBinder.BindModelAsync(modelBindingContext);

            if (modelBindingResult.IsModelSet)
            {
                _validator.Validate(
                    operationContext.ValidatorProvider,
                    modelState,
                    modelBindingContext.ValidationState,
                    modelBindingResult.Key,
                    modelBindingResult.Model);
            }

            return(modelBindingResult);
        }
예제 #2
0
        public void OnProvidersExecuted(ApiDescriptionProviderContext context)
        {
            var typeProvider = new DynamicTypeBuilder(typeBindingRepo);

            foreach (var route in voyagerRoutes)
            {
                var descriptor = new ApiDescription
                {
                    HttpMethod       = route.Method,
                    ActionDescriptor = new Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor
                    {
                        RouteValues = new Dictionary <string, string>()
                    },
                    RelativePath = route.Template,
                };
                var validBindingSources = new[] { BindingSource.Form, BindingSource.Query, BindingSource.Path };
                foreach (var property in typeBindingRepo.GetProperties(route.RequestType))
                {
                    if (validBindingSources.Contains(property.BindingSource))
                    {
                        descriptor.ParameterDescriptions.Add(new ApiParameterDescription
                        {
                            Name   = property.Name.ToLower(),
                            Type   = property.Property.PropertyType,
                            Source = property.BindingSource,
                            ParameterDescriptor = new Microsoft.AspNetCore.Mvc.Abstractions.ParameterDescriptor {
                                Name = property.Description
                            }
                        });
                    }
                }

                var requestBodyType = typeProvider.CreateBodyType(route.RequestType);
                if (requestBodyType != null)
                {
                    var requestModel = modelMetadataProvider.GetMetadataForType(requestBodyType);
                    descriptor.ParameterDescriptions.Add(new ApiParameterDescription
                    {
                        Type          = requestBodyType,
                        Source        = BindingSource.Body,
                        ModelMetadata = requestModel
                    });
                }
                descriptor.ActionDescriptor.RouteValues["controller"] = GetTopRoute(route.Template);
                descriptor.SupportedRequestFormats.Add(new ApiRequestFormat {
                    MediaType = "application/json"
                });
                var responseType = GetResponseType(route.RequestType);
                if (responseType != null)
                {
                    var response = new ApiResponseType();
                    response.ApiResponseFormats.Add(new ApiResponseFormat {
                        MediaType = "application/json"
                    });
                    response.ModelMetadata = modelMetadataProvider.GetMetadataForType(responseType);
                    descriptor.SupportedResponseTypes.Add(response);
                }
                context.Results.Add(descriptor);
            }
        }
        public async Task <ModelBindingResult> BindModelAsync(
            ParameterDescriptor parameter,
            OperationBindingContext operationContext)
        {
            if (parameter == null)
            {
                throw new ArgumentNullException(nameof(parameter));
            }

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

            var metadata            = _modelMetadataProvider.GetMetadataForType(parameter.ParameterType);
            var modelBindingContext = ModelBindingContext.CreateBindingContext(
                operationContext,
                metadata,
                parameter.BindingInfo,
                parameter.Name);

            var modelBindingResult = await operationContext.ModelBinder.BindModelAsync(modelBindingContext);

            if (modelBindingResult.IsModelSet)
            {
                _validator.Validate(
                    operationContext.ActionContext,
                    operationContext.ValidatorProvider,
                    modelBindingContext.ValidationState,
                    modelBindingResult.Key,
                    modelBindingResult.Model);
            }

            return(modelBindingResult);
        }
예제 #4
0
        /// <summary>
        /// Clears <see cref="ModelStateDictionary"/> entries for <see cref="ModelMetadata"/>.
        /// </summary>
        /// <param name="modelMetadata">The <see cref="ModelMetadata"/>.</param>
        /// <param name="modelKey">The entry to clear. </param>
        /// <param name="modelMetadataProvider">The <see cref="IModelMetadataProvider"/>.</param>
        public static void ClearValidationStateForModel(
            [NotNull] Type modelType,
            [NotNull] ModelStateDictionary modelstate,
            [NotNull] IModelMetadataProvider metadataProvider,
            string modelKey)
        {
            // If modelkey is empty, we need to iterate through properties (obtained from ModelMetadata) and
            // clear validation state for all entries in ModelStateDictionary that start with each property name.
            // If modelkey is non-empty, clear validation state for all entries in ModelStateDictionary
            // that start with modelKey
            if (string.IsNullOrEmpty(modelKey))
            {
                var modelMetadata = metadataProvider.GetMetadataForType(modelType);
                if (modelMetadata.IsCollectionType)
                {
                    var elementType = GetElementType(modelMetadata.ModelType);
                    modelMetadata = metadataProvider.GetMetadataForType(elementType);
                }

                foreach (var property in modelMetadata.Properties)
                {
                    var childKey = property.BinderModelName ?? property.PropertyName;
                    modelstate.ClearValidationState(childKey);
                }
            }
            else
            {
                modelstate.ClearValidationState(modelKey);
            }
        }
예제 #5
0
        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 metadata            = _modelMetadataProvider.GetMetadataForType(parameter.ParameterType);
            var modelBindingContext = DefaultModelBindingContext.CreateBindingContext(
                controllerContext,
                new CompositeValueProvider(controllerContext.ValueProviders),
                metadata,
                parameter.BindingInfo,
                parameter.Name);

            if (parameter.BindingInfo?.BinderModelName != null)
            {
                // The name was set explicitly, always use that as the prefix.
                modelBindingContext.ModelName = parameter.BindingInfo.BinderModelName;
            }
            else if (modelBindingContext.ValueProvider.ContainsPrefix(parameter.Name))
            {
                // We have a match for the parameter name, use that as that prefix.
                modelBindingContext.ModelName = parameter.Name;
            }
            else
            {
                // No match, fallback to empty string as the prefix.
                modelBindingContext.ModelName = string.Empty;
            }

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

            await binder.BindModelAsync(modelBindingContext);

            var modelBindingResult = modelBindingContext.Result;

            if (modelBindingResult != null && modelBindingResult.Value.IsModelSet)
            {
                _validator.Validate(
                    controllerContext,
                    modelBindingContext.ValidationState,
                    modelBindingResult.Value.Key,
                    modelBindingResult.Value.Model);
            }

            return(modelBindingResult);
        }
예제 #6
0
        private ApiDescription CreateApiDescription(
            ControllerActionDescriptor action,
            string httpMethod,
            string groupName)
        {
            var parsedTemplate = ParseTemplate(action);

            var apiDescription = new ApiDescription()
            {
                ActionDescriptor = action,
                GroupName        = groupName,
                HttpMethod       = httpMethod,
                RelativePath     = GetRelativePath(parsedTemplate),
            };

            var templateParameters = parsedTemplate?.Parameters?.ToList() ?? new List <TemplatePart>();

            GetParameters(apiDescription, action.Parameters, templateParameters);

            var responseMetadataAttributes = GetResponseMetadataAttributes(action);

            // We only provide response info if we can figure out a type that is a user-data type.
            // Void /Task object/IActionResult will result in no data.
            var declaredReturnType = GetDeclaredReturnType(action);

            // Now 'simulate' an action execution. This attempts to figure out to the best of our knowledge
            // what the logical data type is using filters.
            var runtimeReturnType = GetRuntimeReturnType(declaredReturnType, responseMetadataAttributes);

            // We might not be able to figure out a good runtime return type. If that's the case we don't
            // provide any information about outputs. The workaround is to attribute the action.
            if (runtimeReturnType == typeof(void))
            {
                // As a special case, if the return type is void - we want to surface that information
                // specifically, but nothing else. This can be overridden with a filter/attribute.
                apiDescription.ResponseType = runtimeReturnType;
            }
            else if (runtimeReturnType != null)
            {
                apiDescription.ResponseType = runtimeReturnType;

                apiDescription.ResponseModelMetadata = _modelMetadataProvider.GetMetadataForType(
                    modelAccessor: null,
                    modelType: runtimeReturnType);

                var formats = GetResponseFormats(
                    action,
                    responseMetadataAttributes,
                    declaredReturnType,
                    runtimeReturnType);

                foreach (var format in formats)
                {
                    apiDescription.SupportedResponseFormats.Add(format);
                }
            }

            return(apiDescription);
        }
예제 #7
0
        /// <summary>
        /// Gets <see cref="ModelExplorer"/> for named <paramref name="expression"/> in given
        /// <paramref name="viewData"/>.
        /// </summary>
        /// <param name="expression">Expression name, relative to <c>viewData.Model</c>.</param>
        /// <param name="viewData">
        /// The <see cref="ViewDataDictionary"/> that may contain the <paramref name="expression"/> value.
        /// </param>
        /// <param name="metadataProvider">The <see cref="IModelMetadataProvider"/>.</param>
        /// <returns>
        /// <see cref="ModelExplorer"/> for named <paramref name="expression"/> in given <paramref name="viewData"/>.
        /// </returns>
        public static ModelExplorer FromStringExpression(
            string expression,
            [NotNull] ViewDataDictionary viewData,
            IModelMetadataProvider metadataProvider)
        {
            var viewDataInfo = ViewDataEvaluator.Eval(viewData, expression);

            if (viewDataInfo == null)
            {
                // Try getting a property from ModelMetadata if we couldn't find an answer in ViewData
                var propertyExplorer = viewData.ModelExplorer.GetExplorerForProperty(expression);
                if (propertyExplorer != null)
                {
                    return(propertyExplorer);
                }
            }

            if (viewDataInfo != null)
            {
                if (viewDataInfo.Container == viewData &&
                    viewDataInfo.Value == viewData.Model &&
                    string.IsNullOrEmpty(expression))
                {
                    // Nothing for empty expression in ViewData and ViewDataEvaluator just returned the model. Handle
                    // using FromModel() for its object special case.
                    return(FromModel(viewData, metadataProvider));
                }

                ModelExplorer containerExplorer = viewData.ModelExplorer;
                if (viewDataInfo.Container != null)
                {
                    containerExplorer = metadataProvider.GetModelExplorerForType(
                        viewDataInfo.Container.GetType(),
                        viewDataInfo.Container);
                }

                if (viewDataInfo.PropertyInfo != null)
                {
                    // We've identified a property access, which provides us with accurate metadata.
                    var containerType     = viewDataInfo.Container?.GetType() ?? viewDataInfo.PropertyInfo.DeclaringType;
                    var containerMetadata = metadataProvider.GetMetadataForType(viewDataInfo.Container.GetType());
                    var propertyMetadata  = containerMetadata.Properties[viewDataInfo.PropertyInfo.Name];

                    Func <object, object> modelAccessor = (ignore) => viewDataInfo.Value;
                    return(containerExplorer.GetExplorerForExpression(propertyMetadata, modelAccessor));
                }
                else if (viewDataInfo.Value != null)
                {
                    // We have a value, even though we may not know where it came from.
                    var valueMetadata = metadataProvider.GetMetadataForType(viewDataInfo.Value.GetType());
                    return(containerExplorer.GetExplorerForExpression(valueMetadata, viewDataInfo.Value));
                }
            }

            // Treat the expression as string if we don't find anything better.
            var stringMetadata = metadataProvider.GetMetadataForType(typeof(string));

            return(viewData.ModelExplorer.GetExplorerForExpression(stringMetadata, modelAccessor: null));
        }
예제 #8
0
        /// <summary>
        /// Gets a <see cref="ModelExplorer"/> for the provided model value and model <see cref="Type"/>.
        /// </summary>
        /// <param name="modelType">The model <see cref="Type"/>.</param>
        /// <param name="model">The model value.</param>
        /// <returns>A <see cref="ModelExplorer"/>.</returns>
        /// <remarks>
        /// <para>
        /// A <see cref="ModelExplorer"/> created by <see cref="GetExplorerForExpression(Type, object)"/>
        /// represents the result of executing an arbitrary expression against the model contained
        /// in the current <see cref="ModelExplorer"/> instance.
        /// </para>
        /// <para>
        /// The returned <see cref="ModelExplorer"/> will have the current instance set as its <see cref="Container"/>.
        /// </para>
        /// </remarks>
        public ModelExplorer GetExplorerForExpression(Type modelType, object model)
        {
            if (modelType == null)
            {
                throw new ArgumentNullException(nameof(modelType));
            }

            var metadata = _metadataProvider.GetMetadataForType(modelType);

            return(GetExplorerForExpression(metadata, model));
        }
        private List <Field> GetMetadata(T data)
        {
            var          metadata = _provider.GetMetadataForType(typeof(T));
            List <Field> Fields   = new List <Field>();

            foreach (var prop in metadata.Properties.Where(pm => pm.ShowForDisplay))
            {
                Type type  = prop.ModelType;
                var  field = new Field
                {
                    DisplayName = prop.DisplayName,
                    IsRequired  = prop.IsRequired,
                };
                if (prop.TemplateHint == "ServerSide")
                {
                    field.ServerSide = true;
                }
                if (prop.IsComplexType)
                {
                    field.Name       = prop.PropertyName + "Id";
                    field.Value      = data?.GetType().GetProperty(field.Name).GetValue(data)?.ToString();
                    field.IsRequired = metadata.Properties.SingleOrDefault(pm => pm.PropertyName == field.Name).IsRequired;
                    field.Type       = "select";
                    object[] parameters = { null };
                    if (!field.ServerSide)
                    {
                        field.Items = typeof(DataAccessLayer <T>).GetMethod(nameof(GetSelectList), BindingFlags.NonPublic | BindingFlags.Instance)
                                      .MakeGenericMethod(prop.ModelType)
                                      .Invoke(obj: this, parameters: parameters) as List <Field.Item>;
                    }
                }
                else
                {
                    field.Name = prop.PropertyName;
                    field.Type = prop.ModelType.Name;
                    object value = data?.GetType().GetProperty(prop.PropertyName).GetValue(data);
                    if (value is DateTime valueDatetime)
                    {
                        field.Value = valueDatetime.ToString("o");
                    }
                    else
                    {
                        if (field.Type == "Boolean" && value == null)
                        {
                            value = false;
                        }
                        field.Value = value?.ToString();
                    }
                }
                Fields.Add(field);
            }
            return(Fields);
        }
예제 #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ViewDataDictionary"/> class.
 /// </summary>
 /// <param name="metadataProvider">
 /// <see cref = "IModelMetadataProvider" /> instance used to calculate
 /// <see cref="ViewDataDictionary.ModelMetadata"/> values.
 /// </param>
 /// <param name="modelState"><see cref="ModelStateDictionary"/> instance for this scope.</param>
 /// <param name="declaredModelType">
 /// <see cref="Type"/> of <see cref="Model"/> values expected. Used to set
 /// <see cref="ViewDataDictionary.ModelMetadata"/> when <see cref="Model"/> is <c>null</c>.
 /// </param>
 /// <remarks>
 /// For use when creating a derived <see cref="ViewDataDictionary"/> for a new top-level scope.
 /// </remarks>
 protected ViewDataDictionary(
     [NotNull] IModelMetadataProvider metadataProvider,
     [NotNull] ModelStateDictionary modelState,
     [NotNull] Type declaredModelType)
     : this(metadataProvider,
            modelState,
            declaredModelType,
            data : new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase),
            templateInfo : new TemplateInfo())
 {
     // This is the core constructor called when Model is unknown. Base ModelMetadata on the declared type.
     ModelMetadata = _metadataProvider.GetMetadataForType(() => null, _declaredModelType);
 }
        public void CreateValidators_GetsNumericValidator_ForNumericType(Type modelType)
        {
            // Arrange
            var provider = new NumericClientModelValidatorProvider();
            var metadata = _metadataProvider.GetMetadataForType(modelType);

            var providerContext = new ClientValidatorProviderContext(metadata, GetValidatorItems(metadata));

            // Act
            provider.CreateValidators(providerContext);

            // Assert
            var validatorItem = Assert.Single(providerContext.Results);

            Assert.IsType <NumericClientModelValidator>(validatorItem.Validator);
        }
예제 #12
0
        Task IModelBinder.BindModelAsync(ModelBindingContext bindingContext)
        {
            var stepTypeValue = bindingContext.ValueProvider.GetValue("StepType");
            var stepType      = Type.GetType(stepTypeValue.ToString());
            RequestHelpFormVariant requestHelpFormVariant = Enum.Parse <RequestHelpFormVariant>(bindingContext.ValueProvider.GetValue("FormVariant").FirstValue);

            int.TryParse(bindingContext.ValueProvider.GetValue("ReferringGroupId").FirstValue, out int groupId);
            Enum.TryParse <SupportActivities>(bindingContext.ValueProvider.GetValue("SelectedSupportActivity").FirstValue, out SupportActivities selectedSupportActivity);
            bindingContext.ModelMetadata = _provider.GetMetadataForType(stepType);
            switch (stepType.Name)
            {
            case nameof(RequestHelpRequestStageViewModel):
                bindingContext.Result = ModelBindingResult.Success(BindRequestStage(bindingContext, requestHelpFormVariant, groupId).Result);
                break;

            case nameof(RequestHelpDetailStageViewModel):
                bindingContext.Result = ModelBindingResult.Success(BindDetailStage(bindingContext, requestHelpFormVariant, selectedSupportActivity, groupId).Result);
                break;

            case nameof(RequestHelpReviewStageViewModel):
                bindingContext.Result = ModelBindingResult.Success(BindReviewStage(bindingContext));
                break;
            }

            return(Task.CompletedTask);
        }
예제 #13
0
        public void Validate(ActionContext actionContext, ValidationStateDictionary validationState, string prefix, object model)
        {
            var requiredErrorsNotHandledByFv = RemoveImplicitRequiredErrors(actionContext);

            // Apply any customizations made with the CustomizeValidatorAttribute
            var metadata = model == null ? null : _modelMetadataProvider.GetMetadataForType(model.GetType());

            if (model != null)
            {
                var customizations = GetCustomizations(actionContext, model.GetType(), prefix);
                actionContext.HttpContext.Items["_FV_Customizations"] = Tuple.Create(model, customizations);
            }

            // Setting as to whether we should run only FV or FV + the other validator providers
            var validatorProvider = _runMvcValidation ? _compositeProvider : _fvProvider;

            var visitor = new FluentValidationVisitor(
                actionContext,
                validatorProvider,
                _validatorCache,
                _modelMetadataProvider,
                validationState)
            {
                ValidateChildren = _implicitValidationEnabled
            };

            visitor.Validate(metadata, prefix, model);

            // Re-add errors that we took out if FV didn't add a key.
            ReApplyImplicitRequiredErrorsNotHandledByFV(requiredErrorsNotHandledByFv);

            // Remove duplicates. This can happen if someone has implicit child validation turned on and also adds an explicit child validator.
            RemoveDuplicateModelstateEntries(actionContext);
        }
예제 #14
0
        public virtual Task <ModelBindingResult> BindModelAsync(
            IValueProvider valueProvider,
            ModelStateDictionary modelState,
            ParameterDescriptor parameter,
            object value)
        {
            if (valueProvider == null)
            {
                throw new ArgumentNullException(nameof(valueProvider));
            }

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

            var metadata = _modelMetadataProvider.GetMetadataForType(parameter.ParameterType);
            var binder   = _modelBinderFactory.CreateBinder(new ModelBinderFactoryContext
            {
                BindingInfo = parameter.BindingInfo,
                Metadata    = metadata,
                CacheToken  = parameter,
            });

            return(BindModelAsync(
                       binder,
                       valueProvider,
                       modelState,
                       parameter,
                       metadata,
                       value));
        }
        /// <summary>
        /// Creates a <see cref="PagePropertyModel"/> for the <paramref name="property"/>.
        /// </summary>
        /// <param name="property">The <see cref="PropertyInfo"/>.</param>
        /// <returns>The <see cref="PagePropertyModel"/>.</returns>
        protected virtual PagePropertyModel CreatePropertyModel(PropertyInfo property)
        {
            if (property == null)
            {
                throw new ArgumentNullException(nameof(property));
            }

            var propertyAttributes = property.GetCustomAttributes(inherit: true);

            var propertyMetadata = _modelMetadataProvider.GetMetadataForProperty(property.DeclaringType, property.Name);
            var bindingInfo      = BindingInfo.GetBindingInfo(propertyAttributes, propertyMetadata);

            if (bindingInfo == null)
            {
                // Look for binding info on the handler if nothing is specified on the property.
                // This allows BindProperty attributes on handlers to apply to properties.
                var handlerType       = property.DeclaringType;
                var handlerAttributes = handlerType.GetCustomAttributes(inherit: true);
                var handlerMetadata   = _modelMetadataProvider.GetMetadataForType(property.DeclaringType);
                bindingInfo = BindingInfo.GetBindingInfo(handlerAttributes, handlerMetadata);
            }

            var model = new PagePropertyModel(property, propertyAttributes)
            {
                PropertyName = property.Name,
                BindingInfo  = bindingInfo,
            };

            return(model);
        }
        public ApiParameterDescription Create(
            BindingSource bindingSource,
            string name,
            Type type,
            bool isOptional = true)
        {
            var modelType = _metadataProvider.GetMetadataForType(type);

            return(new ApiParameterDescription
            {
                Name = name,
                Type = type,
                Source = bindingSource,
                ParameterDescriptor = new Microsoft.AspNetCore.Mvc.Abstractions.ParameterDescriptor
                {
                    Name = name,
                    ParameterType = type
                },
                ModelMetadata = modelType,
                RouteInfo = new ApiParameterRouteInfo
                {
                    IsOptional = isOptional
                }
            });
        }
        public Task <IBinding?> TryCreateAsync(BindingProviderContext context)
        {
            _ = context ?? throw new ArgumentNullException(nameof(context));

            var attribute = context.Parameter.GetCustomAttributes(inherit: false).OfType <IBindingSourceMetadata>().FirstOrDefault();

            if (!(attribute is null))
            {
                var modelMetadata = _modelMetadataProvider switch
                {
                    ModelMetadataProvider provider => provider.GetMetadataForParameter(context.Parameter),
                    _ => _modelMetadataProvider.GetMetadataForType(context.Parameter.ParameterType)
                };

                var modelBinderFactoryContext = new ModelBinderFactoryContext
                {
                    Metadata    = modelMetadata,
                    BindingInfo = BindingInfo.GetBindingInfo(context.Parameter.GetCustomAttributes())
                };

                var modelBinder = _modelBinderFactory.CreateBinder(modelBinderFactoryContext);

                return(Task.FromResult <IBinding?>(new MvcModelBinding(context.Parameter, modelMetadata, modelBinder, _mvcOptions.ValueProviderFactories)));
            }

            return(Task.FromResult <IBinding?>(null));
        }
    }
예제 #18
0
        private static BindingInfo[] GetParameterBindingInfo(
            IModelBinderFactory modelBinderFactory,
            IModelMetadataProvider modelMetadataProvider,
            ControllerActionDescriptor actionDescriptor)
        {
            var parameters = actionDescriptor.Parameters;

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

            var parameterBindingInfo = new BindingInfo[parameters.Count];

            for (var i = 0; i < parameters.Count; i++)
            {
                var parameter = parameters[i];
                var metadata  = modelMetadataProvider.GetMetadataForType(parameter.ParameterType);
                var binder    = modelBinderFactory.CreateBinder(new ModelBinderFactoryContext
                {
                    BindingInfo = parameter.BindingInfo,
                    Metadata    = metadata,
                    CacheToken  = parameter,
                });

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

            return(parameterBindingInfo);
        }
예제 #19
0
        // Internal for unit testing.
        internal BindingSource InferBindingSourceForParameter(ParameterModel parameter)
        {
            var parameterType = parameter.ParameterInfo.ParameterType;

            if (ParameterExistsInAllRoutes(parameter.Action, parameter.ParameterName))
            {
                return(BindingSource.Path);
            }
            else
            {
                ModelMetadata parameterMetadata;
                if (_modelMetadataProvider is ModelMetadataProvider modelMetadataProvider)
                {
                    parameterMetadata = modelMetadataProvider.GetMetadataForParameter(parameter.ParameterInfo);
                }
                else
                {
                    parameterMetadata = _modelMetadataProvider.GetMetadataForType(parameter.ParameterInfo.ParameterType);
                }

                if (parameterMetadata != null)
                {
                    var bindingSource = parameterMetadata.IsComplexType ?
                                        BindingSource.Body :
                                        BindingSource.Query;

                    return(bindingSource);
                }
            }

            return(null);
        }
        public static ModelMetadata ModelMetadata(this object model, IModelMetadataProvider modelMetadataProvider)
        {
            var type          = ModelType(model);
            var modelMetaData = modelMetadataProvider.GetMetadataForType(type);

            return(modelMetaData);
        }
예제 #21
0
    protected virtual IEnumerable <ApiResponseType> GetApiResponseTypes()
    {
        foreach (var apiResponse in _options.SupportedResponseTypes)
        {
            apiResponse.ModelMetadata = _modelMetadataProvider.GetMetadataForType(apiResponse.Type);

            foreach (var responseTypeMetadataProvider in _mvcOptions.OutputFormatters.OfType <IApiResponseTypeMetadataProvider>())
            {
                var formatterSupportedContentTypes = responseTypeMetadataProvider.GetSupportedContentTypes(null, apiResponse.Type);
                if (formatterSupportedContentTypes == null)
                {
                    continue;
                }

                foreach (var formatterSupportedContentType in formatterSupportedContentTypes)
                {
                    apiResponse.ApiResponseFormats.Add(new ApiResponseFormat
                    {
                        Formatter = (IOutputFormatter)responseTypeMetadataProvider,
                        MediaType = formatterSupportedContentType
                    });
                }
            }
        }

        return(_options.SupportedResponseTypes);
    }
        private IList <ApiParameterDescription> GetParameters(ApiParameterContext context)
        {
            // First, get parameters from the model-binding/parameter-binding side of the world.
            if (context.ActionDescriptor.Parameters != null)
            {
                foreach (var actionParameter in context.ActionDescriptor.Parameters)
                {
                    var visitor = new PseudoModelBindingVisitor(context, actionParameter);

                    ModelMetadata metadata = null;
                    if (_mvcOptions.AllowValidatingTopLevelNodes &&
                        actionParameter is ControllerParameterDescriptor controllerParameterDescriptor &&
                        _modelMetadataProvider is ModelMetadataProvider provider)
                    {
                        // The default model metadata provider derives from ModelMetadataProvider
                        // and can therefore supply information about attributes applied to parameters.
                        metadata = provider.GetMetadataForParameter(controllerParameterDescriptor.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(actionParameter.ParameterType);
                    }

                    var bindingContext = ApiParameterDescriptionContext.GetContext(
                        metadata,
                        actionParameter.BindingInfo,
                        propertyName: actionParameter.Name);
                    visitor.WalkParameter(bindingContext);
                }
예제 #23
0
        /// <summary>
        /// Binds the model.
        /// </summary>
        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            var typeFieldNamePrefix = !string.IsNullOrEmpty(bindingContext.ModelName)
                                ? $"{bindingContext.ModelName}."
                                : "";

            var typeNameResult = bindingContext.ValueProvider
                                 .GetValue($"{typeFieldNamePrefix}{_baseType.Name}Type");

            if (typeNameResult == null || typeNameResult.Count() != 1)
            {
                return;
            }

            var typeName = typeNameResult.First();
            var derivedModelBinderKvp = _derivedModelBinders.First(kvp => kvp.Key.Name == typeName);
            var derivedModelType      = derivedModelBinderKvp.Key;
            var derivedModelBinder    = derivedModelBinderKvp.Value;

            ModelBindingResult result;

            using (bindingContext.EnterNestedScope(
                       _modelMetadataProvider.GetMetadataForType(derivedModelType),
                       bindingContext.FieldName,
                       bindingContext.ModelName,
                       model: null
                       ))
            {
                await derivedModelBinder.BindModelAsync(bindingContext);

                result = bindingContext.Result;
            }

            bindingContext.Result = result;
        }
    public string TranslateDisplayName <TEnum>(TEnum e) where TEnum : struct
    {
        var a    = _metadataProvider.GetMetadataForType(e.GetType());
        var name = a.EnumGroupedDisplayNamesAndValues.FirstOrDefault(t => t.Value == a.EnumNamesAndValues[e.ToString()]).Key.Name;

        return(name ?? e.ToString());
    }
        public async Task <ModelBindingResult> BindModelAsync(
            [NotNull] ParameterDescriptor parameter,
            [NotNull] ModelStateDictionary modelState,
            [NotNull] OperationBindingContext operationContext)
        {
            var metadata            = _modelMetadataProvider.GetMetadataForType(parameter.ParameterType);
            var modelBindingContext = GetModelBindingContext(
                parameter.Name,
                metadata,
                parameter.BindingInfo,
                modelState,
                operationContext);

            var modelBindingResult = await operationContext.ModelBinder.BindModelAsync(modelBindingContext);

            if (modelBindingResult != null && modelBindingResult.IsModelSet)
            {
                var key           = modelBindingResult.Key;
                var modelExplorer = new ModelExplorer(
                    _modelMetadataProvider,
                    metadata,
                    modelBindingResult.Model);

                var validationContext = new ModelValidationContext(
                    modelBindingContext.BindingSource,
                    operationContext.ValidatorProvider,
                    modelState,
                    modelExplorer);
                _validator.Validate(validationContext, modelBindingResult.ValidationNode);
            }

            return(modelBindingResult);
        }
예제 #26
0
        /// <summary>
        /// Populate missing or incomplete properties from model metadata.
        /// </summary>
        /// <param name="fieldInfo">The <c>ExcelColumnInfoCollection</c> to populate.</param>
        /// <param name="itemType">The type of item whose metadata this is being populated from.</param>
        /// <param name="data">The collection of values being serialised. (Not used, provided for use by derived
        /// types.)</param>
        protected virtual void PopulateFieldInfoFromMetadata(ExcelColumnInfoCollection fieldInfo,
                                                             Type itemType,
                                                             IEnumerable <object> data)
        {
            // Populate missing attribute information from metadata.
            var metadata = _modelMetadataProvider.GetMetadataForType(itemType);

            if (metadata != null && metadata.Properties != null)
            {
                foreach (var modelProp in metadata.Properties)
                {
                    var propertyName = modelProp.PropertyName;

                    if (!fieldInfo.Contains(propertyName))
                    {
                        continue;
                    }

                    var field     = fieldInfo[propertyName];
                    var attribute = field.ExcelAttribute;

                    if (!field.IsExcelHeaderDefined)
                    {
                        field.Header = modelProp.DisplayName ?? propertyName;
                    }

                    if (attribute != null && attribute.UseDisplayFormatString)
                    {
                        field.FormatString = modelProp.DisplayFormatString;
                    }
                }
            }
        }
 private bool IsComplexTypeParameter(ParameterModel parameter)
 {
     // No need for information from attributes on the parameter. Just use its type.
     return(_modelMetadataProvider
            .GetMetadataForType(parameter.ParameterInfo.ParameterType)
            .IsComplexType);
 }
        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (!int.TryParse(bindingContext.ValueProvider.GetValue("id").FirstValue, out int productId))
            {
                throw new Exception("The product id was not provided");
            }

            var editModel = new ProductConfigurationEditModel
            {
                Fields = productRepository.GetProductFields(productId)
            };

            for (int i = 0; i < editModel.Fields.Count; i++)
            {
                BaseField     field         = editModel.Fields[i];
                ModelMetadata modelMetadata = modelMetadataProvider.GetMetadataForType(field.GetType());
                IModelBinder  modelBinder   = modelBinderFactory.CreateBinder(new ModelBinderFactoryContext
                {
                    Metadata   = modelMetadata,
                    CacheToken = modelMetadata
                });

                string modelName = $"{bindingContext.BinderModelName}.Fields[{i}]".TrimStart('.');
                using (var scope = bindingContext.EnterNestedScope(modelMetadata, modelName, modelName, field))
                {
                    await modelBinder.BindModelAsync(bindingContext);
                }
            }

            bindingContext.Result = ModelBindingResult.Success(editModel);
        }
        /// <inheritdoc />
        public void Validate(
            ActionContext actionContext,
            IModelValidatorProvider validatorProvider,
            ValidationStateDictionary validationState,
            string prefix,
            object model)
        {
            if (actionContext == null)
            {
                throw new ArgumentNullException(nameof(actionContext));
            }

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

            var visitor = new ValidationVisitor(
                actionContext,
                validatorProvider,
                _validatorCache,
                _modelMetadataProvider,
                validationState);

            var metadata = model == null ? null : _modelMetadataProvider.GetMetadataForType(model.GetType());

            visitor.Validate(metadata, prefix, model);
        }
    public static ModelMetadata GetMetadataForProperty(
        this IModelMetadataProvider provider,
        Type containerType,
        string propertyName)
    {
        if (provider == null)
        {
            throw new ArgumentNullException(nameof(provider));
        }

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

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

        var containerMetadata = provider.GetMetadataForType(containerType);

        var propertyMetadata = containerMetadata.Properties[propertyName];

        if (propertyMetadata == null)
        {
            var message = Resources.FormatCommon_PropertyNotFound(containerType, propertyName);
            throw new ArgumentException(message, nameof(propertyName));
        }

        return(propertyMetadata);
    }
		private static ModelMetadata GetMetadataFromProvider(Func<object> modelAccessor, Type modelType, string propertyName, Type containerType, IModelMetadataProvider provider)
		{
			if (containerType != null && !string.IsNullOrWhiteSpace(propertyName))
			{
				return provider.GetMetadataForProperty(modelAccessor, containerType, propertyName);
			}

			return provider.GetMetadataForType(modelAccessor, modelType);
		}