Exemple #1
0
        /// <summary>
        /// Validates a single node (not including children)
        /// </summary>
        /// <param name="metadata">Model Metadata</param>
        /// <param name="validationContext">Validation Context</param>
        /// <param name="container">The container.</param>
        /// <returns>True if validation passes successfully</returns>
        private static bool ShallowValidate(ModelMetadata metadata, InternalValidationContext validationContext, object container)
        {
            bool isValid = true;

            // Use the DependencyResolver to find any validators appropriate for this type
            IEnumerable <IValidator> validators = validationContext.Provider.GetValidators(metadata.ModelType, validationContext.Scope);

            foreach (IValidator validator in validators)
            {
                IValidatorSelector selector = new DefaultValidatorSelector();
                var context = new ValidationContext(metadata.Model, new PropertyChain(), selector);

                ValidationResult result = validator.Validate(context);

                foreach (ValidationFailure error in result.Errors)
                {
                    if (!validationContext.ModelState.ContainsKey(error.PropertyName))
                    {
                        validationContext.ModelState.Add(error.PropertyName, new ModelState
                        {
                            Value = new ValueProviderResult(error.AttemptedValue, error.AttemptedValue.ToString(), CultureInfo.CurrentCulture)
                        });
                    }

                    validationContext.ModelState.AddModelError(error.PropertyName, error.ErrorMessage);
                    isValid = false;
                }
            }
            return(isValid);
        }
 private bool ValidateNodeAndChildren(ModelMetadata metadata, InternalValidationContext validationContext, object container)
 {
     bool isValid = true;
     object model = metadata.Model;
     // Optimization: we don't need to recursively traverse the graph for null and primitive types
     if (model != null && model.GetType().IsSimpleType())
     {
         return ShallowValidate(metadata, validationContext, container);
     }
     // Check to avoid infinite recursion. This can happen with cycles in an object graph.
     if (validationContext.Visited.Contains(model))
     {
         return true;
     }
     validationContext.Visited.Add(model);
     // Validate the children first - depth-first traversal
     var enumerableModel = model as IEnumerable;
     if (enumerableModel == null)
     {
         isValid = ValidateProperties(metadata, validationContext);
     }
     else
     {
         isValid = ValidateElements(enumerableModel, validationContext);
     }
     if (isValid && metadata.Model != null)
     {
         // Don't bother to validate this node if children failed.
         isValid = ShallowValidate(metadata, validationContext, container);
     }
     // Pop the object so that it can be validated again in a different path
     validationContext.Visited.Remove(model);
     return isValid;
 }
 private bool ValidateProperties(ModelMetadata metadata, InternalValidationContext validationContext)
 {
     bool isValid = true;
     var propertyScope = new PropertyScope();
     validationContext.KeyBuilders.Push(propertyScope);
     foreach (ModelMetadata childMetadata in validationContext.MetadataProvider.GetMetadataForProperties(
         metadata.Model, GetRealModelType(metadata)))
     {
         propertyScope.PropertyName = childMetadata.PropertyName;
         if (!ValidateNodeAndChildren(childMetadata, validationContext, metadata.Model))
         {
             isValid = false;
         }
     }
     validationContext.KeyBuilders.Pop();
     return isValid;
 }
 private bool ValidateElements(IEnumerable model, InternalValidationContext validationContext)
 {
     bool isValid = true;
     Type elementType = GetElementType(model.GetType());
     ModelMetadata elementMetadata = validationContext.MetadataProvider.GetMetadataForType(null, elementType);
     var elementScope = new ElementScope { Index = 0 };
     validationContext.KeyBuilders.Push(elementScope);
     foreach (object element in model)
     {
         elementMetadata.Model = element;
         if (!ValidateNodeAndChildren(elementMetadata, validationContext, model))
         {
             isValid = false;
         }
         elementScope.Index++;
     }
     validationContext.KeyBuilders.Pop();
     return isValid;
 }
Exemple #5
0
        /// <summary>
        /// Pick out validation errors and turn these into a suitable exception structure
        /// </summary>
        /// <param name="actionContext">Action Context</param>
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            ModelStateDictionary modelState = actionContext.ModelState;

            if (modelState.IsValid)
            {
                // Only perform the FluentValidation if we've not already failed validation earlier on
                IDependencyScope scope = actionContext.Request.GetDependencyScope();
                var mvp = scope.GetService(typeof(IFluentValidatorProvider)) as IFluentValidatorProvider;

                if (mvp != null)
                {
                    ModelMetadataProvider metadataProvider = actionContext.GetMetadataProvider();

                    foreach (KeyValuePair <string, object> argument in actionContext.ActionArguments)
                    {
                        if (argument.Value != null && !argument.Value.GetType().IsSimpleType())
                        {
                            ModelMetadata metadata = metadataProvider.GetMetadataForType(
                                () => argument.Value,
                                argument.Value.GetType()
                                );

                            var validationContext = new InternalValidationContext
                            {
                                MetadataProvider = metadataProvider,
                                ActionContext    = actionContext,
                                ModelState       = actionContext.ModelState,
                                Visited          = new HashSet <object>(),
                                KeyBuilders      = new Stack <IKeyBuilder>(),
                                RootPrefix       = String.Empty,
                                Provider         = mvp,
                                Scope            = scope
                            };

                            ValidateNodeAndChildren(metadata, validationContext, null);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Pick out validation errors and turn these into a suitable exception structure
        /// </summary>
        /// <param name="actionContext">Action Context</param>
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            ModelStateDictionary modelState = actionContext.ModelState;

            if (modelState.IsValid)
            {
                // Only perform the FluentValidation if we've not already failed validation earlier on
                IDependencyScope scope = actionContext.Request.GetDependencyScope();
                var mvp = scope.GetService(typeof(IFluentValidatorProvider)) as IFluentValidatorProvider;

                if (mvp != null)
                {
                    ModelMetadataProvider metadataProvider = actionContext.GetMetadataProvider();

                    foreach (KeyValuePair<string, object> argument in actionContext.ActionArguments)
                    {
                        if (argument.Value != null && !argument.Value.GetType().IsSimpleType())
                        {
                            ModelMetadata metadata = metadataProvider.GetMetadataForType(
                                    () => argument.Value,
                                    argument.Value.GetType()
                                );

                            var validationContext = new InternalValidationContext
                            {
                                MetadataProvider = metadataProvider,
                                ActionContext = actionContext,
                                ModelState = actionContext.ModelState,
                                Visited = new HashSet<object>(),
                                KeyBuilders = new Stack<IKeyBuilder>(),
                                RootPrefix = String.Empty,
                                Provider = mvp,
                                Scope = scope
                            };

                            ValidateNodeAndChildren(metadata, validationContext, null);
                        }
                    }
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Validates a single node (not including children)
        /// </summary>
        /// <param name="metadata">Model Metadata</param>
        /// <param name="validationContext">Validation Context</param>
        /// <param name="container">The container.</param>
        /// <returns>True if validation passes successfully</returns>
        private static bool ShallowValidate(ModelMetadata metadata, InternalValidationContext validationContext, object container)
        {
            bool   isValid = true;
            string key     = null;

            // Use the DependencyResolver to find any validators appropriate for this type
            IEnumerable <IValidator> validators = validationContext.Provider.GetValidators(metadata.ModelType, validationContext.Scope);

            foreach (IValidator validator in validators)
            {
                IValidatorSelector selector = new DefaultValidatorSelector();
                ValidationContext  context  = new ValidationContext(metadata.Model, new PropertyChain(), selector);

                ValidationResult result = validator.Validate(context);
                foreach (var error in result.Errors)
                {
                    if (key == null)
                    {
                        key = validationContext.RootPrefix;
                        foreach (IKeyBuilder keyBuilder in validationContext.KeyBuilders.Reverse())
                        {
                            key = keyBuilder.AppendTo(key);
                        }

                        // Avoid adding model errors if the model state already contains model errors for that key
                        // We can't perform this check earlier because we compute the key string only when we detect an error
                        if (!validationContext.ModelState.IsValidField(key))
                        {
                            return(false);
                        }
                    }
                    validationContext.ModelState.AddModelError(key, JsonConvert.SerializeObject(error));
                    isValid = false;
                }
            }
            return(isValid);
        }
 private bool ValidateProperties(ModelMetadata metadata, InternalValidationContext validationContext)
 {
     bool isValid = true;
     PropertyScope propertyScope = new PropertyScope();
     validationContext.KeyBuilders.Push(propertyScope);
     foreach (ModelMetadata childMetadata in validationContext.MetadataProvider.GetMetadataForProperties(
         metadata.Model, GetRealModelType(metadata)))
     {
         propertyScope.PropertyName = childMetadata.PropertyName;
         if (!ValidateNodeAndChildren(childMetadata, validationContext, metadata.Model))
         {
             isValid = false;
         }
     }
     validationContext.KeyBuilders.Pop();
     return isValid;
 }
        private bool ValidateNodeAndChildren(ModelMetadata metadata, InternalValidationContext validationContext, object container)
        {
            object model = metadata.Model;
            bool isValid = true;

            // Optimization: we don't need to recursively traverse the graph for null and primitive types
            if (model == null || model.GetType().IsSimpleType())
            {
                return ShallowValidate(metadata, validationContext, container);
            }

            // Check to avoid infinite recursion. This can happen with cycles in an object graph.
            if (validationContext.Visited.Contains(model))
            {
                return true;
            }
            validationContext.Visited.Add(model);

            // Validate the children first - depth-first traversal
            IEnumerable enumerableModel = model as IEnumerable;
            if (enumerableModel == null)
            {
                isValid = ValidateProperties(metadata, validationContext);
            }
            else
            {
                isValid = ValidateElements(enumerableModel, validationContext);
            }
            if (isValid)
            {
                // Don't bother to validate this node if children failed.
                isValid = ShallowValidate(metadata, validationContext, container);
            }

            // Pop the object so that it can be validated again in a different path
            validationContext.Visited.Remove(model);

            return isValid;
        }
        private bool ValidateElements(IEnumerable model, InternalValidationContext validationContext)
        {
            bool isValid = true;
            Type elementType = GetElementType(model.GetType());
            ModelMetadata elementMetadata = validationContext.MetadataProvider.GetMetadataForType(null, elementType);

            ElementScope elementScope = new ElementScope() { Index = 0 };
            validationContext.KeyBuilders.Push(elementScope);
            foreach (object element in model)
            {
                elementMetadata.Model = element;
                if (!ValidateNodeAndChildren(elementMetadata, validationContext, model))
                {
                    isValid = false;
                }
                elementScope.Index++;
            }
            validationContext.KeyBuilders.Pop();
            return isValid;
        }
        /// <summary>
        /// Validates a single node (not including children)
        /// </summary>
        /// <param name="metadata">Model Metadata</param>
        /// <param name="validationContext">Validation Context</param>
        /// <param name="container">The container.</param>
        /// <returns>True if validation passes successfully</returns>
        private static bool ShallowValidate(ModelMetadata metadata, InternalValidationContext validationContext, object container)
        {
            bool isValid = true;
            string key = null;

            // Use the DependencyResolver to find any validators appropriate for this type
            IEnumerable<IValidator> validators = validationContext.Provider.GetValidators(metadata.ModelType, validationContext.Scope);

            foreach (IValidator validator in validators)
            {
                IValidatorSelector selector = new DefaultValidatorSelector();
                ValidationContext context = new ValidationContext(metadata.Model, new PropertyChain(), selector);

                ValidationResult result = validator.Validate(context);
                foreach (var error in result.Errors)
                {
                    if (key == null)
                    {
                        key = validationContext.RootPrefix;
                        foreach (IKeyBuilder keyBuilder in validationContext.KeyBuilders.Reverse())
                        {
                            key = keyBuilder.AppendTo(key);
                        }

                        // Avoid adding model errors if the model state already contains model errors for that key
                        // We can't perform this check earlier because we compute the key string only when we detect an error
                        if (!validationContext.ModelState.IsValidField(key))
                        {
                            return false;
                        }
                    }
                    validationContext.ModelState.AddModelError(key, JsonConvert.SerializeObject(error));
                    isValid = false;
                }
            }
            return isValid;
        }
        /// <summary>
        /// Validates a single node (not including children)
        /// </summary>
        /// <param name="metadata">Model Metadata</param>
        /// <param name="validationContext">Validation Context</param>
        /// <param name="container">The container.</param>
        /// <returns>True if validation passes successfully</returns>
        private static bool ShallowValidate(ModelMetadata metadata, InternalValidationContext validationContext, object container)
        {
            bool isValid = true;

            // Use the DependencyResolver to find any validators appropriate for this type
            IEnumerable<IValidator> validators = validationContext.Provider.GetValidators(metadata.ModelType, validationContext.Scope);

            foreach (IValidator validator in validators)
            {
                IValidatorSelector selector = new DefaultValidatorSelector();
                var context = new ValidationContext(metadata.Model, new PropertyChain(), selector);

                ValidationResult result = validator.Validate(context);

                foreach (ValidationFailure error in result.Errors)
                {
                    if (!validationContext.ModelState.ContainsKey(error.PropertyName))
                    {
                        validationContext.ModelState.Add(error.PropertyName, new ModelState
                        {
                            Value = new ValueProviderResult(error.AttemptedValue, error.AttemptedValue.ToString(), CultureInfo.CurrentCulture)
                        });
                    }

                    validationContext.ModelState.AddModelError(error.PropertyName, error.ErrorMessage);
                    isValid = false;
                }
            }
            return isValid;
        }