コード例 #1
0
        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            ModelBindingContext context4key = new ModelBindingContext(bindingContext)
            {
                ModelMetadata = actionContext.GetMetadataProvider().GetMetadataForType(null, typeof(TKey)),
                ModelName     = ModelNameBuilder.CreatePropertyModelName(bindingContext.ModelName, "key")
            };

            if (actionContext.Bind(context4key))
            {
                TKey key = (TKey)context4key.Model;
                ModelBindingContext context4Value = new ModelBindingContext(bindingContext)
                {
                    ModelMetadata = actionContext.GetMetadataProvider().GetMetadataForType(null, typeof(TValue)),
                    ModelName     = ModelNameBuilder.CreatePropertyModelName(bindingContext.ModelName, "value")
                };
                if (actionContext.Bind(context4Value))
                {
                    TValue value = (TValue)context4Value.Model;
                    bindingContext.Model = new KeyValuePair <TKey, TValue>(key, value);
                    return(true);
                }
            }
            return(false);
        }
コード例 #2
0
        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 propertyMetadata.GetValidators(actionContext.GetValidatorProviders()))
                    {
                        foreach (ModelValidationResult propertyResult in propertyValidator.Validate(model))
                        {
                            string thisErrorKey = ModelBindingHelper.CreatePropertyModelName(propertyKeyRoot, propertyResult.MemberName);
                            modelState.AddModelError(thisErrorKey, propertyResult.Message);
                        }
                    }
                }
            }
        }
コード例 #3
0
        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
            };

            actionContext.Bind(dtoBindingContext);
            return((ComplexModelDto)dtoBindingContext.Model);
        }
コード例 #4
0
        // Used when the ValueProvider contains the collection to be bound as a single element, e.g. the raw value
        // is [ "1", "2" ] and needs to be converted to an int[].
        internal static List <TElement> BindSimpleCollection(HttpActionContext actionContext, ModelBindingContext bindingContext, object rawValue, CultureInfo culture)
        {
            if (rawValue == null)
            {
                return(null); // nothing to do
            }

            List <TElement> boundCollection = new List <TElement>();

            object[] rawValueArray = ModelBindingHelper.RawValueToObjectArray(rawValue);
            foreach (object rawValueElement in rawValueArray)
            {
                ModelBindingContext innerBindingContext = new ModelBindingContext(bindingContext)
                {
                    ModelMetadata = actionContext.GetMetadataProvider().GetMetadataForType(null, typeof(TElement)),
                    ModelName     = bindingContext.ModelName,
                    ValueProvider = new CompositeValueProvider
                    {
                        new ElementalValueProvider(bindingContext.ModelName, rawValueElement, culture), // our temporary provider goes at the front of the list
                        bindingContext.ValueProvider
                    }
                };

                object boundValue = null;
                if (actionContext.Bind(innerBindingContext))
                {
                    boundValue = innerBindingContext.Model;
                    bindingContext.ValidationNode.ChildNodes.Add(innerBindingContext.ValidationNode);
                }
                boundCollection.Add(ModelBindingHelper.CastOrDefault <TElement>(boundValue));
            }

            return(boundCollection);
        }
コード例 #5
0
        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));
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            ModelMetadataProvider metadataProvider =
                MetadataProvider ?? actionContext.GetMetadataProvider();

            ModelBindingHelper.ValidateBindingContext(
                bindingContext,
                typeof(KeyValuePair <TKey, TValue>),
                true /* allowNullModel */
                );

            TKey key;
            bool keyBindingSucceeded = actionContext.TryBindStrongModel(
                bindingContext,
                "key",
                metadataProvider,
                out key
                );

            TValue value;
            bool   valueBindingSucceeded = actionContext.TryBindStrongModel(
                bindingContext,
                "value",
                metadataProvider,
                out value
                );

            if (keyBindingSucceeded && valueBindingSucceeded)
            {
                bindingContext.Model = new KeyValuePair <TKey, TValue>(key, value);
            }
            return(keyBindingSucceeded || valueBindingSucceeded);
        }
コード例 #8
0
        internal static List <TElement> BindComplexCollectionFromIndexes(
            HttpActionContext actionContext,
            ModelBindingContext bindingContext,
            IEnumerable <string> indexNames
            )
        {
            bool indexNamesIsFinite;

            if (indexNames != null)
            {
                indexNamesIsFinite = true;
            }
            else
            {
                indexNamesIsFinite = false;
                indexNames         = CollectionModelBinderUtil.GetZeroBasedIndexes();
            }

            List <TElement> boundCollection = new List <TElement>();

            foreach (string indexName in indexNames)
            {
                string fullChildName = ModelBindingHelper.CreateIndexModelName(
                    bindingContext.ModelName,
                    indexName
                    );
                ModelBindingContext childBindingContext = new ModelBindingContext(bindingContext)
                {
                    ModelMetadata = actionContext
                                    .GetMetadataProvider()
                                    .GetMetadataForType(null, typeof(TElement)),
                    ModelName = fullChildName
                };

                bool   didBind    = false;
                object boundValue = null;
                if (actionContext.Bind(childBindingContext))
                {
                    didBind    = true;
                    boundValue = childBindingContext.Model;

                    // merge validation up
                    bindingContext.ValidationNode.ChildNodes.Add(
                        childBindingContext.ValidationNode
                        );
                }

                // infinite size collection stops on first bind failure
                if (!didBind && !indexNamesIsFinite)
                {
                    break;
                }

                boundCollection.Add(ModelBindingHelper.CastOrDefault <TElement>(boundValue));
            }

            return(boundCollection);
        }
コード例 #9
0
        public bool BindDotKeyModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            if (!typeof(TKey).CanConvertFromString())
            {
                return(false);
            }

            var valueProvider = bindingContext.ValueProvider as IEnumerableValueProvider;

            if (valueProvider == null)
            {
                return(false);
            }

            var boundDictionary = new Dictionary <TKey, TValue>();
            var keyPrefix       = bindingContext.ModelName + ".";
            var keyEntries      = valueProvider.GetKeysFromPrefix(bindingContext.ModelName);

            foreach (var keyEntry in keyEntries)
            {
                var fullChildName = keyEntry.Value;
                if (!fullChildName.StartsWith(keyPrefix, StringComparison.Ordinal))
                {
                    continue;
                }

                var key = (TKey)TypeConversionHelpers.ConvertSimpleType(CultureInfo.CurrentCulture, keyEntry.Key, typeof(TKey));

                var childBindingContext = new ModelBindingContext(bindingContext)
                {
                    ModelMetadata = actionContext.GetMetadataProvider().GetMetadataForType(null, typeof(TValue)),
                    ModelName     = fullChildName
                };
                if (!actionContext.Bind(childBindingContext))
                {
                    continue;
                }

                var boundValue = (TValue)childBindingContext.Model;

                bindingContext.ValidationNode.ChildNodes.Add(childBindingContext.ValidationNode);

                boundDictionary.Add(key, boundValue);
            }
            if (boundDictionary.Count == 0)
            {
                return(false);
            }

            ModelBinderHelpers.CreateOrMergeDictionary(bindingContext, boundDictionary, () => new Dictionary <TKey, TValue>());
            return(true);
        }
コード例 #10
0
        private List <TElement> BindSimpleCollection(HttpActionContext actionContext, ModelBindingContext bindingContext, object rawValue, CultureInfo culture)
        {
            List <object> list1 = new List <object>();

            if (!(rawValue is string))
            {
                IEnumerable enumerable = rawValue as IEnumerable;
                if (null != enumerable)
                {
                    list1 = enumerable.Cast <object>().ToList();
                }
            }
            else
            {
                list1 = new List <object> {
                    rawValue
                };
            }

            List <TElement> list2 = new List <TElement>();

            foreach (object obj in list1)
            {
                ModelBindingContext subContext = new ModelBindingContext(bindingContext)
                {
                    ModelMetadata = actionContext.GetMetadataProvider().GetMetadataForType(null, typeof(TElement)),
                    ModelName     = bindingContext.ModelName,
                    ValueProvider = new CompositeValueProvider {
                        new ElementalValueProvider(bindingContext.ModelName, obj, culture), bindingContext.ValueProvider
                    }
                };
                if (actionContext.Bind(subContext))
                {
                    list2.Add((TElement)subContext.Model);
                }
                else
                {
                    list1.Add(null);
                }
            }
            return(list2);
        }
コード例 #11
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);
                        }
                    }
                }
            }
        }
コード例 #12
0
        private List <TElement> BindComplexCollection(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            string key = ModelNameBuilder.CreatePropertyModelName(bindingContext.ModelName, "index");
            ValueProviderResult  result = bindingContext.ValueProvider.GetValue(key);
            IEnumerable <string> indexes;
            bool useZeroBasedIndexes = false;

            if (null == result)
            {
                indexes             = this.GetZeroBasedIndexes();
                useZeroBasedIndexes = true;
            }
            else
            {
                indexes = (IEnumerable <string>)result.ConvertTo(typeof(IEnumerable <string>));
            }
            List <TElement> list = new List <TElement>();

            foreach (string index in indexes)
            {
                ModelBindingContext subContext = new ModelBindingContext(bindingContext)
                {
                    ModelMetadata = actionContext.GetMetadataProvider().GetMetadataForType(null, typeof(TElement)),
                    ModelName     = ModelNameBuilder.CreateIndexModelName(bindingContext.ModelName, index)
                };
                bool failed = true;
                if (actionContext.Bind(subContext))
                {
                    list.Add((TElement)subContext.Model);
                    failed = false;
                }
                if (failed && useZeroBasedIndexes)
                {
                    return(list);
                }
            }
            return(list);
        }
コード例 #13
0
        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);
        }
コード例 #14
0
        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            if (!CanBindType(bindingContext.ModelType))
            {
                return(false);
            }
            if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName))
            {
                return(false);
            }
            //创建针对目标类型的空对象
            var ins = DynamicModelBuilder.GetInstance <IContact>(parent: bindingContext.ModelType, propAttrProvider: () =>
            {
                return(new List <PropertyCustomAttributeUnit>
                {
                    new PropertyCustomAttributeUnit
                    {
                        prop_name = "phone",
                        attrs = new List <PropertyCustomAttribute>
                        {
                            new PropertyCustomAttribute
                            {
                                attr_type = "System.ComponentModel.DataAnnotations.RequiredAttribute,System.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
                                ctor_arg_types = "",
                                ctor_arg_values = new object[0],
                                error_msg = "姓名不能为空",
                                error_msg_res_name = "",
                                error_msg_res_type = ""
                            }
                        }
                    }
                });
            });

            //bindingContext.Model = Activator.CreateInstance(bindingContext.ModelType);
            bindingContext.Model = ins;

            //创建针对目标类型的ComplexModelDto
            //创建ModelBindingContext,并将ComplexModelDto作为Model,驱动新一轮的Model绑定
            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);

            //从ComplexModelDto获取相应的值并为相应的属性赋值
            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);
        }