实现ModelState.IsValid

返回
Author Avatar
钢翼
2017-06-03
编程
380

在mvc的控制器中,提供了ModelState.IsValid供我们很方便的验证模型。但是有个缺点就是必须将模型作为Action的参数,才能使用。

很多时候我们并不直接将模型放到参数中,特别是复杂模型,我们习惯使用json字符串传输,后台进行反序列话,这个时候我们又想对模型进行验证。怎么办呢。

这个时候我们可以自定义一个方法来实现ModelState.IsValid的功能,直接贴代码。

 private IEnumerable<ModelValidator> GetValidators<T>(T obj, ModelValidatorProvider validatorProvider)
        {
            ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => obj, typeof(T));
            foreach (var validator in validatorProvider.GetValidators(metadata, ControllerContext))
            {
                yield return validator;
            }

            foreach (var propertyMetadata in metadata.Properties)
            {
                foreach (var validator in validatorProvider.GetValidators(propertyMetadata, ControllerContext))
                {
                    yield return validator;
                }
            }
        }

        /// <summary>  
        /// 模型验证  
        /// </summary> 
        protected bool IsValid<T>(T obj, out string errMsg)
        {
            errMsg = "";
            //ModelValidatorProvider validatorProvider = new XmlModelValidatorProvider();//xml配置文件验证模式
            ModelValidatorProvider validatorProvider = new DataAnnotationsModelValidatorProvider();//默认验证模式
            var flag = true;
            foreach (var validator in GetValidators(obj, validatorProvider))
            {
                var validationResults = validator.Validate(obj);
                if (validationResults.Any())
                {
                    flag = false;
                    var errMsgs = new List<string>();
                    foreach (var validationResult in validationResults)
                    {
                        ModelState.AddModelError(validator.GetType().Name, validationResult.Message);//将错误输出到错误集合
                        errMsgs.Add(validationResult.Message);
                    }
                    errMsg = string.Join("rn", errMsgs);//将错误合并到错误信息中
                }
            }
            return flag;
        }

这样我们就可以将模型作为IsValid的方法的参数进行验证了,这里我将errMsg传出去是因为如果Action返回的是json的话,用不到Html.ValidationSummary(),所以才加上这个errMsg。

这里还可以扩展模型验证,让其支持List<T>的校验,毕竟这种形式的数据也是很常见的。