internal static bool ValidateObject(object o, List<ValidationResultInfo> validationErrors, HttpActionContext actionContext)
        {
            // create a model validation node for the object
            ModelMetadataProvider metadataProvider = actionContext.GetMetadataProvider();
            string modelStateKey = String.Empty;
            ModelValidationNode validationNode = CreateModelValidationNode(o, metadataProvider, actionContext.ModelState, modelStateKey);
            validationNode.ValidateAllProperties = true;

            // add the node to model state
            ModelState modelState = new ModelState();
            modelState.Value = new ValueProviderResult(o, String.Empty, CultureInfo.CurrentCulture);
            actionContext.ModelState.Add(modelStateKey, modelState);

            // invoke validation
            validationNode.Validate(actionContext);

            if (!actionContext.ModelState.IsValid)
            {
                foreach (var modelStateItem in actionContext.ModelState)
                {
                    foreach (ModelError modelError in modelStateItem.Value.Errors)
                    {
                        validationErrors.Add(new ValidationResultInfo(modelError.ErrorMessage, new string[] { modelStateItem.Key }));
                    }
                }
            }

            return actionContext.ModelState.IsValid;
        }
        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            if (!CanBindType(bindingContext.ModelType))
            {
                return false;
            }
            if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName))
            {
                return false;
            }

            bindingContext.Model = Activator.CreateInstance(bindingContext.ModelType);
            ComplexModelDto dto = new ComplexModelDto(bindingContext.ModelMetadata, bindingContext.PropertyMetadata.Values);
            ModelBindingContext subContext = new ModelBindingContext(bindingContext)
            {
                ModelMetadata = actionContext.GetMetadataProvider().GetMetadataForType(() => dto, typeof(ComplexModelDto)),
                ModelName = bindingContext.ModelName
            };
            actionContext.Bind(subContext);

            foreach (KeyValuePair<ModelMetadata, ComplexModelDtoResult> item in dto.Results)
            {
                ModelMetadata propertyMetadata = item.Key;
                ComplexModelDtoResult dtoResult = item.Value;
                if (dtoResult != null)
                {
                    PropertyInfo propertyInfo = bindingContext.ModelType.GetProperty(propertyMetadata.PropertyName);
                    if (propertyInfo.CanWrite)
                    {
                        propertyInfo.SetValue(bindingContext.Model, dtoResult.Model);
                    }
                }
            }
            return true;
        }
 public HttpResponseMessage Get()
 {
     Address address = new Address
     {
         Province = "江苏省",
         City = "苏州市",
         District = "工业园区",
         Street = "星湖街328号"
     };
     Contact contact = new Contact
     {
         Name = "张三",
         PhoneNo = "123456789",
         EmailAddress = "*****@*****.**",
         Address = address
     };
     IBodyModelValidator validator = new DefaultBodyModelValidator();
     HttpActionContext actionContext = new HttpActionContext
     {
         ControllerContext = this.ControllerContext
     };
     ModelMetadataProvider metadataProvider =actionContext.GetMetadataProvider();
     validator.Validate(contact, typeof(Contact), metadataProvider,actionContext, "contact");
     return this.Request.CreateErrorResponse(HttpStatusCode.BadRequest,actionContext.ModelState);
 }
        private ComplexModelDto CreateAndPopulateDto(HttpActionContext actionContext, ModelBindingContext bindingContext, IEnumerable<ModelMetadata> propertyMetadatas)
        {
            ModelMetadataProvider metadataProvider = MetadataProvider ?? actionContext.GetMetadataProvider();

            // create a DTO and call into the DTO binder
            ComplexModelDto originalDto = new ComplexModelDto(bindingContext.ModelMetadata, propertyMetadatas);
            ModelBindingContext dtoBindingContext = new ModelBindingContext(bindingContext)
            {
                ModelMetadata = metadataProvider.GetMetadataForType(() => originalDto, typeof(ComplexModelDto)),
                ModelName = bindingContext.ModelName
            };

            IModelBinder dtoBinder = actionContext.GetBinder(dtoBindingContext);
            dtoBinder.BindModel(actionContext, dtoBindingContext);
            return (ComplexModelDto)dtoBindingContext.Model;
        }
        /// <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();
                IFluentValidatorProvider mvp = scope.GetService(typeof(IFluentValidatorProvider)) as IFluentValidatorProvider;
                mvp = mvp ?? new FluentValidatorProvider(new ScopedValidatorFactory());

                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()
                                );

                            InternalValidationContext 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);
                        }
                    }
                }
            }
        }
        private void ValidateProperties(HttpActionContext actionContext)
        {
            // Based off CompositeModelValidator.
            ModelStateDictionary modelState = actionContext.ModelState;

            // DevDiv Bugs #227802 - Caching problem in ModelMetadata requires us to manually regenerate
            // the ModelMetadata.
            object model = ModelMetadata.Model;
            ModelMetadata updatedMetadata = actionContext.GetMetadataProvider().GetMetadataForType(() => model, ModelMetadata.ModelType);

            foreach (ModelMetadata propertyMetadata in updatedMetadata.Properties)
            {
                // Only want to add errors to ModelState if something doesn't already exist for the property node,
                // else we could end up with duplicate or irrelevant error messages.
                string propertyKeyRoot = ModelBindingHelper.CreatePropertyModelName(ModelStateKey, propertyMetadata.PropertyName);

                if (modelState.IsValidField(propertyKeyRoot))
                {
                    foreach (ModelValidator propertyValidator in actionContext.GetValidators(propertyMetadata))
                    {
                        foreach (ModelValidationResult propertyResult in propertyValidator.Validate(propertyMetadata, model))
                        {
                            string thisErrorKey = ModelBindingHelper.CreatePropertyModelName(propertyKeyRoot, propertyResult.MemberName);
                            modelState.AddModelError(thisErrorKey, propertyResult.Message);
                        }
                    }
                }
            }
        }