Проверка универсального блока приложения проверки свойств - PullRequest
1 голос
/ 13 ноября 2011

У нас есть универсальная собственность

 public class BE
    {
        private List<Admin_Fee> _Admin_Fee = new List<Admin_Fee>();
        [StringLengthValidator(3,
        MessageTemplate = "Fund City Can't be more than 3 Chars")]  
        public MyProperty<string> FUND_CITY { get; set; }

        public MyProperty<int> SomeOtherProperty { get; set; }

        public List<MyPropertyBase> MyDataPoints { get; set; }

    }

Я хочу поместить StingLengthValidator using VAB в Общее свойство, и получаю ошибку, что:

Значение не ожидается тип

Может ли кто-нибудь помочь?

Ответы [ 2 ]

0 голосов
/ 14 ноября 2011

Причина, по которой вы получаете ошибку, довольно проста: вы пытаетесь использовать 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; }
}

Я не тестировал его широко, но, похоже, он работает. У него есть несколько недостатков:

  • Это негибко. Например, он не поддерживает составные валидаторы или другие более сложные сценарии. Возможно, вы могли бы реализовать все эти случаи, но это было бы грязно.
  • Моя реализация использует отражение, которого было бы лучше избегать.
  • Потенциальный бокс типов значений
0 голосов
/ 14 ноября 2011

Я думаю, что проблема здесь в том, как работают валидаторы.StringLengthValidator требует, чтобы строка находилась в определенных параметрах (минимальная и максимальная длина).Однако свойство, на которое вы помещаете этот валидатор, не является строкой, и это ваша проблема.Ваш тип является универсальным T <>, если вы хотите выполнить некоторую проверку длины строки сортировки для этого свойства с использованием атрибутов проверки, вам потребуется создать пользовательский атрибут валидатора.

Пример MVC (MVC нетребуется для части атрибута) - http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx

Общий пример - http://odetocode.com/Blogs/scott/archive/2011/02/21/custom-data-annotation-validator-part-i-server-code.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...