我有一个Case对象,它本身包含许多对象(见下文),它也包含对象。
这些对象可以从实现ValidateObject方法的BaseDto类继承,该类对当前对象执行DataAnnotation验证器,从而返回累积到ValidationResult集合中的验证错误。
我想要将以下混乱的语法转换为可以遍历给定对象的对象层次结构的语法,并且可以遍历每个对象(及其子对象!)实现ValidateObject的代码,执行它。
我现在感觉有点卡住了,所以如果有任何想法,我会很感激的。
cCase.ValidateObject() &
cCase.Object1.ValidateObject() &
cCase.Object2.ValidateObject() &
cCase.Object3.ValidateObject() &
cCase.Object3.ChildObject1.ValidateObject() &
cCase.Object3.ChildObject2.ValidateObject() &
cCase.Object3.ChildObject3.ValidateObject() &
cCase.Object3.ChildObject4.ValidateObject() &
cCase.Object3.ChildObject4.ChildChildObject1.ValidateObject() &
cCase.Object3.ChildObject5.ValidateObject() &
cCase.Object4.ValidateObject() &
cCase.Object4.ChildObject6.ValidateObject();发布于 2012-12-12 23:07:43
您需要使用反射获取从BaseDto类继承的所有字段:
public abstract class BaseDto
{
public abstract bool ValidateObject();
}
// Sample class without nested fields, requiring validation.
public class Case2 : BaseDto
{
public override bool ValidateObject()
{
Console.WriteLine("Validated: " + ToString());
return false;
}
}
// Sample nested class with nested fields, requiring validation.
public class Case1 : BaseDto
{
private Case2 Object1 = new Case2();
private Case2 Object2 = new Case2();
private Stream stream = new MemoryStream();
public override bool ValidateObject()
{
Console.WriteLine("Validated: " + ToString());
return true;
}
}
public class Case : BaseDto
{
private Case1 Object1 = new Case1();
private Case2 Object2 = new Case2();
// don't touch this field
private Stream stream = new MemoryStream();
private Case1 Object3 = new Case1();
public override bool ValidateObject()
{
Console.WriteLine("Validated: " + ToString());
return true;
}
public bool ValidateAll()
{
if (!ValidateObject()) return false;
return ValidateAll(this);
}
private bool ValidateAll(object o)
{
foreach (FieldInfo fieldInfo in o.GetType().GetFields(BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public))
{
BaseDto current = fieldInfo.GetValue(o) as BaseDto;
if(current != null)
{
bool result = current.ValidateObject();
if(!result)
{
return false;
}
return ValidateAll(current);
}
}
return true;
}
}对根对象调用ValidateAll()。在内部,它遍历从BaseDto派生的所有字段,递归地验证它们和其中的所有字段。
发布于 2012-12-12 23:29:59
我会使用如下的扩展方法:
public interface IValidatable
{
bool ValidateObject();
}
public static class ValidateExtensions
{
public static bool ValidateAll(this IValidatable item)
{
if (!item.ValidateObject())
return false;
const BindingFlags flags = BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public;
var type = item.GetType();
var props = type.GetProperties(flags).Select(x => x.GetValue(item));
var fields = type.GetFields(flags).Select(x => x.GetValue(item));
return props
.Concat(fields)
.OfType<IValidatable>()
.Select(x => x.ValidateAll())
.All(x => x);
}
}发布于 2012-12-12 22:49:07
让层次结构中的每个类覆盖ValidateObject()以验证其子对象会更干净:
public override bool ValidateObject()
{
return base.ValidateObject() &
this.Object1.ValidateObject() &
this.Object2.ValidateObject() &
this.Object3.ValidateObject() &
this.Object4.ValidateObject();
}然后客户端可以只在根对象上调用ValidateObject()。
https://stackoverflow.com/questions/13842152
复制相似问题