Причина, по которой вы получаете ошибку, довольно проста: вы пытаетесь использовать 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; }
}
Я не тестировал его широко, но, похоже, он работает. У него есть несколько недостатков:
- Это негибко. Например, он не поддерживает составные валидаторы или другие более сложные сценарии. Возможно, вы могли бы реализовать все эти случаи, но это было бы грязно.
- Моя реализация использует отражение, которого было бы лучше избегать.
- Потенциальный бокс типов значений