.net 企业库对象验证:获取有关验证失败的更多信息

.net 企业库对象验证:获取有关验证失败的更多信息,.net,validation,enterprise-library,.net,Validation,Enterprise Library,我试图对未绑定到UI的对象执行一些验证。例如,我有以下三个课程: public class XDeftable { [ObjectCollectionValidator(typeof(XSchedGroup))] public List<XSchedGroup> SCHED_GROUP { get; set; } } [IdentifyingProperty("TABLE_NAME")] public class XSchedGroup { [ObjectC

我试图对未绑定到UI的对象执行一些验证。例如,我有以下三个课程:

public class XDeftable {
    [ObjectCollectionValidator(typeof(XSchedGroup))]
    public List<XSchedGroup> SCHED_GROUP { get; set; }
}

[IdentifyingProperty("TABLE_NAME")]
public class XSchedGroup {
    [ObjectCollectionValidator(typeof(XJob))]
    public List<XJob> JOB { get; set; }
    [Required]
    public string TABLE_NAME { get; set; }
}

[IdentifyingProperty("JOBNAME")]
public class XJob : ICalendar {
    [Required]
    public string JOBNAME { get; set; }
    [Range(-62, 62)]
    public string SHIFTNUM { get; set; }
    [ObjectCollectionValidator(typeof(XTagNames))]
    public List<XTagNames> TAG_NAMES { get; set; }
}
到目前为止,我已经能够得出以下结论:

public ValidationResults Validate(XDeftable deftable) {
    var results = new ObjectValidator(typeof(XDeftable)).Validate(deftable);
    var detailedResults = new ValidationResults();

    foreach (var item in results) {
        var targetType = item.Target.GetType();

        var identProp = targetType.GetCustomAttribute<IdentifyingProperty>();
        if (identProp != null) {
            var pi = targetType.GetProperty(identProp.Name);
            var newKey = String.Format("{0}[{1}].{2}", targetType.Name, pi.GetValue(item.Target).ToString(), item.Key);
            detailedResults.AddResult(new ValidationResult(item.Message, item.Target, newKey, item.Tag, item.Validator));
        }
        else {
            detailedResults.AddResult(item);
        }
    }

    return detailedResults;
}
公共验证结果验证(XDeftable deftable){ var结果=新的ObjectValidator(typeof(XDeftable)).Validate(deftable); var detailedResults=新的ValidationResults(); foreach(结果中的var项目){ var targetType=item.Target.GetType(); var identProp=targetType.GetCustomAttribute(); 如果(identProp!=null){ var pi=targetType.GetProperty(identProp.Name); var newKey=String.Format(“{0}[{1}].{2}”,targetType.Name,pi.GetValue(item.Target.ToString(),item.Key); detailedResults.AddResult(新的ValidationResult(item.Message、item.Target、newKey、item.Tag、item.Validator)); } 否则{ 详细结果。添加结果(项目); } } 返回详细的结果; }
这至少会返回我“XJob[JOBNAME].SHIFTNUM |字段SHIFTNUM必须介于-62和62之间。”如果有一种方法可以让我获得遵循容器链的结果,我还是喜欢它,例如:XSchedGroup[TABLE_NAME].XJob[JOBNAME].SHIFTNUM我曾经使用过类似的方法

        public class RequiredPropertyAttribute : Attribute
        {
            public bool Required { get { return true; } }
        }
        public class RequiredListAttribute : Attribute
        {
            public bool Required { get { return true; } }
        }
下面是验证。它根据我指定的属性进行检查,并返回需要填充的未填充属性

            public List<string> IterateProperties(object _o)
            {
                List<string> problems = new List<string>();

                foreach (PropertyInfo info in _o.GetType().GetProperties())
                {
                    bool isGenericType = info.PropertyType.IsGenericType;
                    Type infoType = info.PropertyType;

                    if (infoType.IsGenericType && infoType.GetGenericTypeDefinition() == typeof(List<>))
                    {
                        infoType = infoType.GetGenericArguments()[0];

                        if (infoType.IsNested)
                        {
                            System.Collections.IList subObjects = (System.Collections.IList)info.GetValue(_o, null);

                            object[] requiredListAttributes = info.GetCustomAttributes(typeof(RequiredListAttribute), true);
                            if (requiredListAttributes.Length > 0 && subObjects.Count == 0)
                            {
                                problems.Add(String.Format("List {0} in class {1} must have at least 1 row", info.Name, info.PropertyType.ToString()));
                            }
                            else
                            {
                                foreach (object sub in subObjects)
                                {
                                    problems.AddRange(this.IterateProperties(sub));
                                }
                            }
                        }
                    }
                    else
                    {
                        if (infoType.IsNested)
                        {
                            object sub = info.GetValue(_o, null);
                            if (sub != null)
                            {
                                problems.AddRange(this.IterateProperties(sub));
                            }
                        }
                    }


                    object[] attributes = info.GetCustomAttributes(typeof(RequiredPropertyAttribute), true);
                    foreach (object o in attributes)
                    {
                        if (info.GetValue(_o, null) == null)
                        {
                            problems.Add(String.Format("Attribute {0} in class {1} cannot be null", info.Name, info.PropertyType.ToString()));
                        }
                    }
                }

                return problems;
            }
        }
公共列表迭代属性(对象)
{
列表问题=新列表();
foreach(在_o.GetType().GetProperties()中的PropertyInfo信息)
{
bool isGenericType=info.PropertyType.isGenericType;
类型infoType=info.PropertyType;
if(infoType.IsGenericType&&infoType.GetGenericTypeDefinition()==typeof(列表))
{
infoType=infoType.GetGenericArguments()[0];
if(infoType.IsNested)
{
System.Collections.IList子对象=(System.Collections.IList)info.GetValue(_o,null);
object[]requiredListAttributes=info.GetCustomAttributes(typeof(RequiredListAttribute),true);
if(requiredListAttributes.Length>0&&subObjects.Count==0)
{
Add(String.Format(“类{1}中的列表{0}必须至少有一行”、info.Name、info.PropertyType.ToString());
}
其他的
{
foreach(子对象中的对象子对象)
{
problems.AddRange(this.IterateProperties(sub));
}
}
}
}
其他的
{
if(infoType.IsNested)
{
object sub=info.GetValue(_o,null);
如果(sub!=null)
{
problems.AddRange(this.IterateProperties(sub));
}
}
}
object[]attributes=info.GetCustomAttributes(typeof(RequiredPropertyAttribute),true);
foreach(属性中的对象o)
{
if(info.GetValue(_o,null)==null)
{
Add(String.Format(“类{1}中的属性{0}不能为null”)、info.Name、info.PropertyType.ToString();
}
}
}
退货问题;
}
}

我不需要操作键,而是使用Tag属性,因为这正是它的用途(“标记的含义由使用ValidationResults的客户端代码决定”)

因此,坚持你的方法,比如:

public ValidationResults Validate(XDeftable deftable)
{
    var results = new ObjectValidator(typeof(XDeftable)).Validate(deftable);
    var detailedResults = new ValidationResults();

    Microsoft.Practices.EnterpriseLibrary.Validation.ValidationResult result = null;

    foreach (var item in results)
    {
        result = item;

        var targetType = item.Target.GetType();

        var attribute = (IdentifyingPropertyAttribute)
                            targetType.GetCustomAttributes(
                                typeof(IdentifyingPropertyAttribute), 
                                false)
                            .SingleOrDefault();

        if (attribute != null)
        {
            var propertyInfo = targetType.GetProperty(attribute.Name);

            if (propertyInfo != null)
            {
                object propertyValue = propertyInfo.GetValue(item.Target) ?? "";

                result = new Microsoft.Practices.EnterpriseLibrary.Validation.ValidationResult(
                            item.Message, 
                            item.Target, 
                            item.Key, 
                            propertyValue.ToString(), 
                            item.Validator);
            }
        }

        detailedResults.AddResult(result);
    }

    return detailedResults;
}

请注意,这不是特定于C#编程语言的。@johnsa对.Net.的编辑标记了解得很好。我已经更改了标题。对不起,但根本不是我想要的。企业库的验证块可以很好地处理我的所有验证。它没有做的是记录足够的信息,以便我对验证失败做任何事情。它只显示验证失败的属性的名称以及失败原因的错误消息。是否有方法获取每个“父级”?如果我能得到对象的整个层次结构,那么对调试/日志记录将非常有帮助。ValidationResult包含对已验证的目标对象的引用。但是,没有关于对象在图形中的位置的概念。我能想到的唯一方法是在每个类中附加一些附加的数据和您想要的信息。例如,所有对象都具有的
ParentName
属性(通过接口或基类),然后可以通过目标对象找到该属性。
public ValidationResults Validate(XDeftable deftable)
{
    var results = new ObjectValidator(typeof(XDeftable)).Validate(deftable);
    var detailedResults = new ValidationResults();

    Microsoft.Practices.EnterpriseLibrary.Validation.ValidationResult result = null;

    foreach (var item in results)
    {
        result = item;

        var targetType = item.Target.GetType();

        var attribute = (IdentifyingPropertyAttribute)
                            targetType.GetCustomAttributes(
                                typeof(IdentifyingPropertyAttribute), 
                                false)
                            .SingleOrDefault();

        if (attribute != null)
        {
            var propertyInfo = targetType.GetProperty(attribute.Name);

            if (propertyInfo != null)
            {
                object propertyValue = propertyInfo.GetValue(item.Target) ?? "";

                result = new Microsoft.Practices.EnterpriseLibrary.Validation.ValidationResult(
                            item.Message, 
                            item.Target, 
                            item.Key, 
                            propertyValue.ToString(), 
                            item.Validator);
            }
        }

        detailedResults.AddResult(result);
    }

    return detailedResults;
}