/// <summary> /// 通过使用验证上下文、验证结果集合和用于指定是否验证所有属性的值,确定指定的属性是否有效。 /// </summary> /// <param name="instance">要验证的对象</param> /// <param name="context">用于描述要验证的对象的上下文</param> /// <param name="validationResults">用于包含每个失败的验证的集合</param> /// <param name="breakOnFirstError">当第一个错误产生时,是否不再进行后续验证</param> /// <param name="metadataType">实体类的元数据描述类,如果传空值,则从实体类的 <see cref="MetadataTypeAttribute"/> 特性上找</param> /// <returns></returns> public static bool TryValidateProperty(object value, ValidationContext context, ICollection <ValidationResult> validationResults, bool breakOnFirstError) { Type propertyType = XFrameworkValidator._store.GetPropertyType(context); string memberName = context.MemberName; //XFrameworkValidator.EnsureValidPropertyType(memberName, propertyType, value); bool result = true; IEnumerable <ValidationAttribute> propertyValidationAttributes = XFrameworkValidator._store.GetPropertyValidationAttributes(context); foreach (XFrameworkValidator.ValidationError current in XFrameworkValidator.GetValidationErrors(value, context, propertyValidationAttributes, breakOnFirstError)) { result = false; if (validationResults != null) { validationResults.Add(current.ValidationResult); } } return(result); }
// 获取实例的属性值 private static IDictionary <ValidationContext, object> GetPropertyValues(object instance, ValidationContext context) { IDictionary <ValidationContext, object> result = new Dictionary <ValidationContext, object>(); TypeRuntimeInfo typeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(instance.GetType()); foreach (var kv in typeRuntime.Invokers) { MemberInvokerBase invoker = kv.Value; if (invoker.MemberType == System.Reflection.MemberTypes.Property) { ValidationContext context2 = XFrameworkValidator.CreateValidationContext(instance, context); context2.MemberName = invoker.Member.Name; if (XFrameworkValidator._store.GetPropertyValidationAttributes(context2).Any <ValidationAttribute>()) { result.Add(context2, invoker.Invoke(instance)); } } } return(result); }
// 验证给定值 private static IEnumerable <XFrameworkValidator.ValidationError> GetValidationErrors(object value, ValidationContext validationContext, IEnumerable <ValidationAttribute> attributes, bool breakOnFirstError) { if (validationContext == null) { throw new ArgumentNullException("validationContext"); } List <XFrameworkValidator.ValidationError> result = new List <XFrameworkValidator.ValidationError>(); XFrameworkValidator.ValidationError item; foreach (ValidationAttribute attr in attributes) { if (!XFrameworkValidator.TryValidate(value, validationContext, attr, out item)) { result.Add(item); if (breakOnFirstError) { break; } } } return(result); }
/// <summary> /// 通过使用验证上下文、验证结果集合和用于指定是否验证所有属性的值,确定指定的对象是否有效。 /// </summary> /// <param name="instance">要验证的对象</param> /// <param name="validationContext">用于描述要验证的对象的上下文</param> /// <param name="validationResults">用于包含每个失败的验证的集合</param> /// <param name="breakOnFirstError">当第一个错误产生时,是否不再进行后续验证</param> /// <returns></returns> public static bool TryValidateObject(object instance, ValidationContext validationContext, ICollection <ValidationResult> validationResults, bool breakOnFirstError)//, Type metadataType = null) { if (instance == null) { throw new ArgumentNullException("instance"); } if (validationContext == null) { throw new ArgumentNullException("validationContext"); } // 取当前实例的所有属性值 IDictionary <ValidationContext, object> propertyValues = XFrameworkValidator.GetPropertyValues(instance, validationContext); List <XFrameworkValidator.ValidationError> list = new List <XFrameworkValidator.ValidationError>(); // 取元数据描述 Type metadataType = null; //if (metadataType == null) //{ Type type = instance.GetType(); MetadataTypeAttribute attr = TypeDescriptor .GetAttributes(type) .OfType <MetadataTypeAttribute>() .FirstOrDefault(); if (attr != null) { metadataType = attr.MetadataClassType; } //} if (metadataType == null) { throw new NullReferenceException(string.Format("type {{{0}}} has no metadata descriptor.", type.Name)); } PropertyDescriptorCollection descriptors = TypeDescriptor.GetProperties(metadataType); // 按照元数据属性的书写顺序逐个验证实体属性 foreach (PropertyDescriptor des in descriptors) { KeyValuePair <ValidationContext, object> kv = propertyValues.FirstOrDefault(x => x.Key.MemberName == des.Name); ValidationContext context = kv.Key; object value = kv.Value; if (context != null) { IEnumerable <ValidationAttribute> validationAttributes = XFrameworkValidator._store.GetPropertyValidationAttributes(context); list.AddRange(XFrameworkValidator.GetValidationErrors(value, context, validationAttributes, breakOnFirstError)); } if (list.Count > 0 && breakOnFirstError) { break; } } bool result = true; foreach (var current in list) { result = false; if (validationResults != null) { validationResults.Add(current.ValidationResult); } } return(result); }