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