您收到错误的原因非常简单:您尝试使用StringLengthValidator 来处理不是字符串的类型(实际上是MyProperty<string>)。
问题是如何验证属性?这很棘手,因为该设计并不能很好地适应验证应用程序块设计。
通常,您只需应用 ObjectValidator 来验证 MyProperty 类,但这并不适合这种情况,因为您似乎打算使用 MyProperty 来保存具有不同规则的各种值,因此您无法真正将验证器属性应用于MyProperty。
我认为您可以使用自定义验证器实现您想要的。我认为您可以将现有的验证器包装在您的自定义验证器中。
这里我假设 MyProperty 看起来像:
public class MyProperty<T>
{
public T Value { get; set; }
}
然后您可以创建自定义验证器 MyPropertyValidator:
public class MyPropertyValidatorAttribute : ValidatorAttribute
{
Microsoft.Practices.EnterpriseLibrary.Validation.Validator validator;
public MyPropertyValidatorAttribute(Type validator, params object[] validatorArgs)
{
this.validator = Activator.CreateInstance(validator, validatorArgs)
as Microsoft.Practices.EnterpriseLibrary.Validation.Validator;
}
protected override Microsoft.Practices.EnterpriseLibrary.Validation.Validator DoCreateValidator(Type targetType)
{
return new MyPropertyValidator(validator);
}
}
public class MyPropertyValidator : Microsoft.Practices.EnterpriseLibrary.Validation.Validator
{
Microsoft.Practices.EnterpriseLibrary.Validation.Validator validator;
public MyPropertyValidator(Microsoft.Practices.EnterpriseLibrary.Validation.Validator validator)
: this(validator.MessageTemplate, validator.Tag)
{
this.validator = validator;
}
public MyPropertyValidator(string message, string tag) : base(message, tag)
{
}
protected override string DefaultMessageTemplate
{
get { return ""; }
}
public override void DoValidate(object objectToValidate, object currentTarget, string key, ValidationResults validationResults)
{
var val = objectToValidate;
Type t = objectToValidate.GetType();
var propInfo = t.GetProperty("Value");
if (propInfo != null)
{
val = propInfo.GetValue(objectToValidate, null);
}
validator.DoValidate(val, currentTarget, key, validationResults);
}
}
然后你可以像这样注释你的类:
public class BE
{
[MyPropertyValidator(
typeof(StringLengthValidator),
0, RangeBoundaryType.Ignore,
3, RangeBoundaryType.Inclusive,
"Fund City Can't be more than 3 Chars",
false)]
public MyProperty<string> FUND_CITY { get; set; }
[MyPropertyValidator(
typeof(RangeValidator),
0, RangeBoundaryType.Inclusive,
10, RangeBoundaryType.Inclusive,
"Must be between 0 and 10",
false)]
public MyProperty<int> SomeOtherProperty { get; set; }
}
我没有对它进行广泛的测试,但它似乎有效。它确实有一些缺点:
- 它不灵活。例如,它不支持复合验证器或其他更复杂的场景。您也许可以实现所有这些情况,但会变得一团糟。
- 我的实现是使用反射,最好避免。
- 值类型的潜在装箱