我有一个场景,我想使用FluentValidation来使用反射进行验证。类似于以下内容:
public class FooValidator : AbstractValidator<Foo>
{
public FooValidator(Foo obj)
{
// Iterate properties using reflection
var properties = ReflectionHelper.GetShallowPropertiesInfo(obj);
foreach (var prop in properties)
{
// Create rule for each property, based on some data coming from other service...
//RuleFor(o => o.Description).NotEmpty().When(o => // this works fine when foo.Description is null
RuleFor(o => o.GetType().GetProperty(prop.Name)).NotEmpty().When(o =>
{
return true; // do other stuff...
});
}
}
}
调用ReflectionHelper.GetShallowPropertiesInfo(obj)
返回对象的“shallow”属性。然后,我为每个属性创建一个规则。这是我获取对象属性的代码:
public static class ReflectionHelper
{
public static IEnumerable<PropertyInfo> GetShallowPropertiesInfo<T>(T o) where T : class
{
var type = typeof(T);
var properties =
from pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
where pi.PropertyType.Module.ScopeName == "CommonLanguageRuntimeLibrary"
&& !(pi.PropertyType.IsGenericType && pi.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>))
select pi;
return properties;
}
}
此代码编译后可以执行
IValidator<Foo> validator = new FooValidator(foo);
var results = validator.Validate(foo);
但是它不能正常工作(验证从来没有失败过),有什么方法可以做到这一点吗?
注:演示代码可在Github中FluentValidationReflection处找到
2条答案
按热度按时间yptwkmov1#
最后我找到了一个可行的解决方案,我创建了一个接收PropertyInfo参数的自定义PropertyValidator:
以及
IRuleBuilder
的扩展方法:这样我就可以修改我的
FooValidator
如下:现在我可以使用反射为特定属性添加规则了
5t7ly7z52#
为了反思我用
(x =〉新对象().获取类型().获取属性(x.过滤器.列名)).非空();