private void ValidateModel(ModelValidDictionary modelValidDictionary, object model, Type modelType, string modelName)
        {
            var modelValid = GetModelValid(model, modelType, modelName);

            if (modelValid != null && modelValid.ValidResults != null && modelValid.ValidResults.Any())
            {
                modelValidDictionary.Add(modelName, modelValid);
            }

            if (model == null)
            {
                return;
            }

            if (modelType == typeof(string) ||
                TypeHelper.IsPrimitiveType(modelType) ||
                TypeHelper.IsNullableValueType(modelType))
            {
                return;
            }

            var properties = modelType.GetProperties(
                BindingFlags.GetProperty |
                BindingFlags.SetProperty |
                BindingFlags.Instance |
                BindingFlags.Public
                );

            if (properties != null || properties.Any())
            {
                foreach (var property in properties)
                {
                    ValidProperty(property, model, modelValidDictionary, modelName);
                }
            }

            if (modelType != typeof(string) &&
                typeof(IEnumerable <>).IsAssignableFrom(modelType))
            {
                Expression callExpr = Expression.Call(
                    Expression.Constant(this),
                    typeof(DefaultModelValidator)
                    .GetMethod("ValidEnumerable",
                               BindingFlags.Static |
                               BindingFlags.NonPublic)
                    .MakeGenericMethod(modelType
                                       .GetInterface(typeof(IEnumerable <>).FullName)
                                       .GetGenericArguments()[0]),
                    Expression.Constant(model, typeof(object)),
                    Expression.Constant(modelValidDictionary, typeof(ModelValidDictionary)),
                    Expression.Constant(modelName, typeof(string))
                    );

                Expression.Lambda <Action>(callExpr).Compile()();
            }
        }
        private void ValidEnumerable <T>(object model, ModelValidDictionary modelValidDictionary, string modelName)
        {
            var enumerables = model as IEnumerable <T>;

            if (enumerables == null)
            {
                return;
            }

            int index     = 0;
            var modelType = typeof(T);

            foreach (var x in enumerables)
            {
                ValidateModel(modelValidDictionary, x, modelType, $"{modelName}.[{index}]");
                index++;
            }
        }
        private void ValidProperty(PropertyInfo property, object model, ModelValidDictionary modelValidDictionary, string modelName)
        {
            var propertyName = modelName + "." + property.Name;
            var validitions  = property.GetCustomAttributes <ValidationAttribute>();
            var modelValid   = new ModelValid();

            ValidValidAttribute(new ValidationContext(model), property.GetValue(model), validitions, modelValid, propertyName);

            if (modelValid != null &&
                modelValid.ValidResults != null &&
                modelValid.ValidResults.Any())
            {
                modelValidDictionary.Add(propertyName, modelValid);
            }

            ValidateModel(
                modelValidDictionary,
                model != null ? property.GetValue(model) : null,
                property.PropertyType,
                propertyName);
        }
        public override ModelValidDictionary Validate(object model, Type modelType, string modelName)
        {
            if (IsRequired == false)
            {
                return(null);
            }

            if (modelName == null)
            {
                modelName = "";
            }

            ModelValidDictionary modelValidDictionary = new ModelValidDictionary();

            if (modelType == null && model == null)
            {
                var validFailure = new ValidFailure()
                {
                    ErrorMessage = "model与modelType都为空"
                };

                var modelValid = new ModelValid();
                modelValid.ValidResults.Add(validFailure);

                modelValidDictionary.Add(modelName, modelValid);
                return(modelValidDictionary);
            }

            if (modelType == null && model != null)
            {
                modelType = model.GetType();
            }

            ValidateModel(modelValidDictionary, model, modelType, modelName);

            return(modelValidDictionary);
        }