コード例 #1
0
        /// <summary>
        /// Validates the given entity and adds the validation errors to the <see cref="ApiController.ModelState"/>, if any.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity to be validated.</typeparam>
        /// <param name="entity">The entity being validated.</param>
        /// <param name="keyPrefix">
        /// The key prefix under which the model state errors would be added in the <see cref="ApiController.ModelState"/>.
        /// </param>
        public void Validate <TEntity>(TEntity entity, string keyPrefix)
        {
            if (Configuration == null)
            {
                throw Error.InvalidOperation(
                          SRResources.TypePropertyMustNotBeNull,
                          typeof(ApiController).Name,
                          "Configuration"
                          );
            }

            IBodyModelValidator validator = Configuration.Services.GetBodyModelValidator();

            if (validator != null)
            {
                ModelMetadataProvider metadataProvider =
                    Configuration.Services.GetModelMetadataProvider();
                Contract.Assert(
                    metadataProvider != null,
                    "GetModelMetadataProvider throws on null."
                    );

                validator.Validate(
                    entity,
                    typeof(TEntity),
                    metadataProvider,
                    ActionContext,
                    keyPrefix
                    );
            }
        }
コード例 #2
0
        protected override async Task <bool> BindAsync(
            ModelBindingContext bindingContext,
            IFormatterBinderMetadata metadata)
        {
            var formatters = _bindingContext.Value.InputFormatters;

            var formatterContext = new InputFormatterContext(_actionContext, bindingContext.ModelType);
            var formatter        = _formatterSelector.SelectFormatter(formatters.ToList(), formatterContext);

            if (formatter == null)
            {
                var unsupportedContentType = Resources.FormatUnsupportedContentType(
                    bindingContext.OperationBindingContext.HttpContext.Request.ContentType);
                bindingContext.ModelState.AddModelError(bindingContext.ModelName, unsupportedContentType);

                // Should always return true so that the model binding process ends here.
                return(true);
            }

            bindingContext.Model = await formatter.ReadAsync(formatterContext);

            // Validate the deserialized object
            var validationContext = new ModelValidationContext(
                bindingContext.OperationBindingContext.MetadataProvider,
                bindingContext.OperationBindingContext.ValidatorProvider,
                bindingContext.ModelState,
                bindingContext.ModelMetadata,
                containerMetadata: null,
                excludeFromValidationFilters: _bodyValidationExcludeFiltersProvider.ExcludeFilters);

            _bodyModelValidator.Validate(validationContext, bindingContext.ModelName);
            return(true);
        }
コード例 #3
0
        public static bool IsValid <TEntity>(this ApiController controller, TEntity entity, string keyPrefix, out ModelStateDictionary modelState)
        {
            HttpConfiguration configuration = controller.Configuration;

            if (configuration == null)
            {
                throw new InvalidOperationException("Configuration cannot be null");
            }
            IBodyModelValidator validator = configuration.Services.GetBodyModelValidator();

            if (validator != null)
            {
                ModelMetadataProvider metadataProvider = configuration.Services.GetModelMetadataProvider();

                HttpActionDescriptor actionDescriptor = controller.Request.GetActionDescriptor();
                if (actionDescriptor == null)
                {
                    throw new InvalidOperationException("Request must have an action descriptor.");
                }

                HttpActionContext actionContext = new HttpActionContext(controller.ControllerContext, actionDescriptor);
                if (!validator.Validate(entity, typeof(TEntity), metadataProvider, actionContext, keyPrefix))
                {
                    modelState = actionContext.ModelState;
                    return(false);
                }
            }

            modelState = null;
            return(true);
        }
コード例 #4
0
        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            ValueProviderResult valueProviderResult = GetCompatibleValueProviderResult(
                bindingContext
                );

            if (valueProviderResult == null)
            {
                return(false); // conversion would have failed
            }

            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
            object model = valueProviderResult.RawValue;

            ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref model);
            bindingContext.Model = model;
            if (bindingContext.ModelMetadata.IsComplexType)
            {
                HttpControllerContext controllerContext = actionContext.ControllerContext;
                if (controllerContext == null)
                {
                    throw Error.Argument(
                              "actionContext",
                              SRResources.TypePropertyMustNotBeNull,
                              typeof(HttpActionContext).Name,
                              "ControllerContext"
                              );
                }

                HttpConfiguration configuration = controllerContext.Configuration;
                if (configuration == null)
                {
                    throw Error.Argument(
                              "actionContext",
                              SRResources.TypePropertyMustNotBeNull,
                              typeof(HttpControllerContext).Name,
                              "Configuration"
                              );
                }

                ServicesContainer services = configuration.Services;
                Contract.Assert(services != null);

                IBodyModelValidator   validator        = services.GetBodyModelValidator();
                ModelMetadataProvider metadataProvider = services.GetModelMetadataProvider();
                if (validator != null && metadataProvider != null)
                {
                    validator.Validate(
                        model,
                        bindingContext.ModelType,
                        metadataProvider,
                        actionContext,
                        bindingContext.ModelName
                        );
                }
            }

            return(true);
        }
コード例 #5
0
        private async Task ExecuteBindingAsyncCore(
            ModelMetadataProvider metadataProvider,
            HttpActionContext actionContext,
            HttpParameterDescriptor paramFromBody,
            Type type,
            HttpRequestMessage request,
            IFormatterLogger formatterLogger,
            CancellationToken cancellationToken)
        {
            var model = await ReadContentAsync(request, type, Formatters, formatterLogger, cancellationToken);

            if (model != null)
            {
                var routeParams = actionContext.ControllerContext.RouteData.Values;

                foreach (var key in routeParams.Keys.Where(k => k != "controller"))
                {
                    var prop = type.GetProperty(key, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public);

                    if (prop == null)
                    {
                        continue;
                    }

                    var descriptor = TypeDescriptor.GetConverter(prop.PropertyType);

                    if (descriptor.CanConvertFrom(typeof(string)))
                    {
                        prop.SetValue(model, descriptor.ConvertFromString(routeParams[key] as string));

                        OnBoundUriKeyToObject(model, key);
                    }
                }
            }

            // Set the merged model in the context.
            SetValue(actionContext, model);

            if (BodyModelValidator != null)
            {
                BodyModelValidator.Validate(model, type, metadataProvider, actionContext, paramFromBody.ParameterName);
            }

            //custom validation from our rules
            if (configuration.PopulateModelState)
            {
                if (model is IEasyPatchModel state)
                {
                    foreach (var error in state.Validate())
                    {
                        actionContext.ModelState.AddModelError(error.Key, error.Value);
                    }
                }
            }
        }
コード例 #6
0
 public bool Validate(object model, Type type, System.Web.Http.Metadata.ModelMetadataProvider metadataProvider, System.Web.Http.Controllers.HttpActionContext actionContext, string keyPrefix)
 {
     if (model.GetType().GetCustomAttributes(true).Contains(new SkipModelValidationAttribute()))
     {
         return(true);
     }
     else
     {
         return(_defaultValidator.Validate(model, type, metadataProvider, actionContext, keyPrefix));
     }
 }
コード例 #7
0
        public override async Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
        {
            if (_willReadBody)
            {
                await actionContext.Request.ReadFormDataAsync(this.Descriptor.Configuration, cancellationToken);
            }

            var model = GetObjectValue(actionContext);

            SetValue(actionContext, model);

            _validator?.Validate(model, this.Descriptor.ParameterType, metadataProvider, actionContext, this.Descriptor.ParameterName);
        }
コード例 #8
0
        /// <summary>
        /// Executes the binding asynchronous.
        /// </summary>
        /// <param name="metadataProvider">The metadata provider.</param>
        /// <param name="actionContext">The action context.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>System.Threading.Tasks.Task.</returns>
        public override async Task ExecuteBindingAsync(
            ModelMetadataProvider metadataProvider,
            HttpActionContext actionContext,
            CancellationToken cancellationToken)
        {
            PatchRequestBase model = await CreatePatchRequest(actionContext.Request, Descriptor.Configuration);

            SetValue(actionContext, model);

            if (_BodyModelValidator != null)
            {
                _BodyModelValidator.Validate(model, Descriptor.ParameterType, metadataProvider, actionContext, Descriptor.ParameterName);
            }
        }
コード例 #9
0
        // Perf-sensitive - keeping the async method as small as possible
        private async Task ExecuteBindingAsyncCore(ModelMetadataProvider metadataProvider, HttpActionContext actionContext,
                                                   HttpParameterDescriptor paramFromBody, Type type, HttpRequestMessage request, IFormatterLogger formatterLogger,
                                                   CancellationToken cancellationToken)
        {
            var model = await ReadContentAsync(request, type, _formatters, formatterLogger, cancellationToken) ??
                        Activator.CreateInstance(type);

            // TODO: Intead of the rest of the code, this can be a better solution:

            /*
             * var fromUriAttribute = new FromUriAttribute();
             * IEnumerable<ValueProviderFactory> valueProviderFactories = fromUriAttribute.GetValueProviderFactories(_httpConfiguration);
             * IModelBinder modelBinder = fromUriAttribute.GetModelBinder(_httpConfiguration, type);
             * ModelBinderParameterBinding mbpb = new ModelBinderParameterBinding(Descriptor, modelBinder, valueProviderFactories);
             * await mbpb.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken);
             * var mergeToModel = actionContext.ActionArguments[Descriptor.ParameterName];
             * // How to merge with model? */

            var routeDataValues   = actionContext.ControllerContext.RouteData.Values;
            var routeParams       = routeDataValues.Except(routeDataValues.Where(v => v.Key == "controller"));
            var queryStringParams = new Dictionary <string, object>(QueryStringValues(request));
            var allUriParams      = routeParams.Union(queryStringParams).ToDictionary(pair => pair.Key, pair => pair.Value);

            foreach (var key in allUriParams.Keys)
            {
                var prop = type.GetProperty(key, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public);

                if (prop == null)
                {
                    continue;
                }

                var descriptor = TypeDescriptor.GetConverter(prop.PropertyType);

                if (descriptor.CanConvertFrom(typeof(string)))
                {
                    prop.SetValue(model, descriptor.ConvertFromString(allUriParams[key] as string));
                }
            }

            // Set the merged model in the context
            SetValue(actionContext, model);

            _bodyModelValidator?.Validate(model, type, metadataProvider, actionContext, paramFromBody.ParameterName);
        }
コード例 #10
0
 public bool Validate(object model, Type type, ModelMetadataProvider metadataProvider, HttpActionContext actionContext, string keyPrefix)
 {
     // Remove the keyPrefix but otherwise let innerValidator do what it normally does.
     return(innerValidator.Validate(model, type, metadataProvider, actionContext, "bla ba"));
 }
コード例 #11
0
 public bool Validate(object model, Type type, ModelMetadataProvider metadataProvider, HttpActionContext actionContext, string keyPrefix)
 {
     return(_validator.Validate(model, type, metadataProvider, actionContext, string.Empty));
 }